...
AWS S3 CLI 명령어
지금까지 S3에 버킷을 생성하고 파일을 저장하려면 웹브라우저 콘솔 화면에 가서 일일히 화면을 눌러 적용해야 했다.
기능상에는 문제는 없지만 웹서비스 자체가 조금 느리다는 점이 사용에 불편함을 느끼게 된다. 거기다 브라우저 한 페이지에 표시되는 파일 갯수 역시 한계가 있다.
하지만 AWS CLI를 이용하면 간편하게 S3 버킷을 제어하고 S3 오브젝트에 접근할 수 있어 활용성이 높아진다.
예를들어 10만 단위의 파일을 한 번에 이동하거나 삭제하고 싶을 때 커맨드를 이용해 패턴을 이용해 빠르게 처리를 할수 있다.
AWS CLI 란?
AWS Command Line Interface(AWS CLI)는 명령줄 셸의 명령을 사용하여 AWS 서비스와 상호 작용할 수 있는 오픈 소스 도구. 최소한의 구성으로 AWS CLI를 사용하면 터미널 프로그램에 있는 명령 프롬프트에서 브라우저 기반 AWS Management Console에서 제공하는 것과 동일한 기능을 구현하는 명령을 실행할 수 있다.
S3 버킷 커맨드
버킷 생성 (mb)
$ aws s3 mb s3://버킷명
$ aws s3 mb s3://test-bucket-inpa
make_bucket: test-bucket-inpa
만일 Amazon S3에 버킷명이 이미 존재하는 경우 거부를 당할 수 있다.
버킷 목록 조회 (ls)
$ aws s3 ls
2022-06-20 20:23:06 inpa-s3-cli
2022-06-23 13:54:49 test-bucket-inpa
버킷 제거 (rb)
$ aws s3 rb s3://버킷명
만일 S3 버킷 안에 내용물이 비어 있지 않을 경우 버킷 제거가 되지 않는다.
이럴 경우 --force 옵션을 주면, S3 버킷 내의 모든 파일을 강제로 삭제하고 그 다음 S3 버킷을 제거하게 된다.
$ aws s3 rb s3://my-fruits --force
delete: s3://my-fruits/apple.txt
delete: s3://my-fruits/cherry.txt
delete: s3://my-fruits/favorites/melon.txt
remove_bucket: my-fruits
S3 파일 커맨드
파일 목록 조회 (ls)
aws s3 ls 커맨드에 버킷명을 인자로 넘겨주면 버킷 내의 파일 목록을 마치 로컬 파일 시스템처럼 조회할 수 있다.
$ aws s3 ls s3://my-fruits
2018-06-02 10:51:55 6 apple.txt
2018-06-02 10:57:19 7 banana.txt
파일 이동 (mv)
$ aws s3 mv test.tar s3://test-bucket-inpa
move: ./test.tar to s3://test-bucket-inpa/test.tar
$ aws s3 ls test-bucket-inpa
2022-06-23 14:08:05 20480 test.tar
파일 삭제 (rm)
버킷명/키명 을 명시하여 삭제할 수 있다.
$ aws s3 rm s3://my-fruits/banana.txt
delete: s3://my-fruits/banana.txt
로컬 → S3 파일 복사 (cp)
로컬 파일을 S3 버킷에 복사하는 것은 곧 S3에 업로드 하는 것과 같다.
# 버킷에 그냥 파일 업로드
$ aws s3 cp bar.txt s3://test-bucket-inpa
upload: ./bar.txt to s3://test-bucket-inpa/bar.txt
# 버킷에 파일명을 변경하고 업로드
$ aws s3 cp bar.txt s3://test-bucket-inpa/change_name_file.txt
upload: ./bar.txt to s3://test-bucket-inpa/change_name_file.txt
# 버킷의 folder1폴더 안에 파일 업로드
$ aws s3 cp bar.txt s3://test-bucket-inpa/folder1/
upload: ./bar.txt to s3://test-bucket-inpa/folder1/bar.txt
S3 → 로컬 파일 복사 (cp)
위에서 로컬에서 버킷으로 파일을 복사하면, 곧 S3에 업로드 동작이 되었다.
이번엔 버킷에서 로컬로 파일을 복사하면, 곧 S3의 파일을 다운 받는 동작이 된다.
$ aws s3 cp s3://버킷명/객체명 <저장할경로>
# 버킷의 bar.txt를 로컬에 현재 dir에 다운
$ aws s3 cp s3://test-bucket-inpa/bar.txt ./
download: s3://test-bucket-inpa/bar.txt to ./bar.txt
# 버킷의 bar.txt를 로컬에 bar2.txt로 파일명 변경하고 다운
$ aws s3 cp s3://test-bucket-inpa/bar.txt ./bar2.txt
download: s3://test-bucket-inpa/bar.txt to ./bar2.txt
S3 → S3 파일 복사 (cp)
# 버킷의 123123.pdf 파일을 folder1/ 에 복사
$ aws s3 cp s3://test-bucket-inpa/123123.pdf s3://test-bucket-inpa/folder1/
copy: s3://test-bucket-inpa/123123.pdf to s3://test-bucket-inpa/folder1/123123.pdf
디렉터리 동기화 (sync)
만일 디렉토리에 있는 파일 전부를 S3에 옮기고 싶을 때 어떻게 할까?
파일을 일일히 커맨드를 옮겨주는 것보다 동기화 기능을 이용하면 간단하게 옮길수 있다.
여기서 동기화란, 내가 가지고 있는 상태와 상대방이 가지고 있는 상태를 일치시킨다는 개념으로 이해하면 된다.
aws s3 sync 커맨드를 이용하여 로컬 디렉터리와 S3 버킷을 동기화 시킬 수 있다.
$ aws s3 sync <동기화 주체> <동기화 대상>
# 버킷의 내용물을 로컬 디렉토리와 동기화 → 로컬로 다운로드
aws s3 sync s3://bucket-name/ ./
# 로컬 디렉토리 내용물을 버킷에 동기화 → S3에 업로드
aws s3 sync ./ s3://bucket-name/
다만 동기화는 파일을 업로드/다운로드 할때 동작되고, 파일 삭제 동작은 하지않는다. (빈 버킷과 동기화되도 내 로컬 파일들이 삭제되지 않는다)
S3 커맨드 옵션
자주 사용하는 cli 명령어 옵션은 --force 강제, --exclude 제외, --include 포함 등이 있다.
하위 디렉토리 포함 (--recursive)
--recursive 옵션과 함께 사용하면 커맨드 적용 범위가 하위 디렉터리까지 적용된다.
예를 들어 aws s3 rm 커맨드를 --recursive 옵션과 함께 사용하면 하위 디렉터리까지 적용되서 모든 파일과 디렉토리가 삭제된다.
반대로 aws s3 cp 커맨드를 --recursive 옵션과 함꼐 사용하면 Bucket에 있는 모든 파일이 복사된다.
$ aws s3 cp . s3://my-fruits --recursive
upload: ./cherry.txt to s3://my-fruits/cherry.txt
upload: ./apple.txt to s3://my-fruits/apple.txt
upload: favorites/melon.txt to s3://my-fruits/favorites/melon.txt # favorites폴더 안에있는 파일 까지 복사
$ aws s3 rm s3://my-fruits/ --recursive
delete: s3://my-fruits/apple.txt
delete: s3://my-fruits/cherry.txt
delete: s3://my-fruits/favorites/melon.txt # 하위 디렉토리 파일까지 모두 삭제
참고로 위에서 배운 aws s3 sync 커맨드는 기본적으로 하위 디렉터리까지 모두 동기화해주기 때문에 별도로 --recursive 옵션이 안먹힌다.
파일 제외 (--exclude)
--exclude 옵션은 명령에서 객체만 제외하도록 규칙을 설정하고 옵션은 지정된 순서대로 적용된다.
# 모든 .txt 파일을 제외하고 나머지 파일을 copy
$ aws s3 cp . s3://my-bucket/path --exclude "*.txt"
# MyFile1.txt, MyFile2.rtf, MyFile88.txt 등을 제외하고 copy
$ aws s3 cp . s3://my-bucket/path --exclude "*.txt" --include "MyFile*.txt"
# 디렉터리 내 파일을 삭제하되 .sh로 끝나는 파일은 남겨두기 위해, --exclude 옵션으로 *.sh 패턴을 지정.
$ aws s3 rm --recursive --exclude "*.sh" s3://test/rm_test/
S3 와일드카드 패턴
와일드카드(wildcard character)는 컴퓨터에서 특정 명령어로 명령을 내릴 때, 여러 파일을 한꺼번에 지정할 목적으로 사용하는 기호를 가리킨다.
주로 특정한 패턴이 있는 문자열 혹은 파일을 찾거나, 긴 이름을 생략할 때 쓰인다.
기본적으로 aws cli는 와일드카드 패턴을 지원하지 않는다.
예로,aws s3 rm abc*커맨드를 실행하면 abc1, abc2, abc3, ... 파일이 지워지지 않는게 아니라 abc* 라는 파일이 지워지게 된다.
다만, --include와 --exclude 옵션과 함께 사용하면 와일드카드 패턴을 지원한다.
위 --exclude 옵션에 할당한 문자열을 보면, "*.txt" 와 같이 와일드카드 문자를 사용한걸 볼 수 있다.
파일 포함 (--include)
--include 옵션은 명령에 지정된 객체만 포함하도록 규칙을 설정하며 옵션은 지정된 순서대로 적용된다
// 모든 .txt 형식의 파일을 포함하여 copy
$ aws s3 cp . s3://my-bucket/path --include "*.txt"
# 모든 .txt 형식의 파일을 포함, 그러나 MyFile로 시작하는 파일명은 제외, 그런데 MyFile1.txt만은 제외하지않고 포함해서 copy
$ aws s3 cp . s3://my-bucket/path --include "*.txt" --exclude "MyFile*.txt" --include "MyFile1.txt"
# .log 파일만 제외한 모든 파일과 하위 디렉토리 파일이 로컬에 복사
$ aws s3 cp s3://BucketName/ ./ --recursive --exclude "*.log" --include "*"
# 특정 날짜의 nginx 로그를 다운로드
$ aws s3 cp s3://BucketName/nginx/ . --recursive --exclude "*" --include "access*2016-10-23*"
# 'imgae-숫자' 로 시작되는 복수 파일만 업로드
$ aws s3 cp /Images s3://test-s3/cp-test/ --recursive --exclude "*" --include "image-*"
upload: ./image-1.jpg to s3://test-s3-squirrel/cp-test/image-1.jpg
upload: ./image-4.jpg to s3://test-s3-squirrel/cp-test/image-4.jpg
upload: ./image-2.jpg to s3://test-s3-squirrel/cp-test/image-2.jpg
upload: ./image-3.png to s3://test-s3-squirrel/cp-test/image-3.png
커맨드 테스트 (--dryrun)
명령어 조합이 애매모호 하여, 실제로 수행결과는 얻지말고 동작만 보고 싶다면, --dryrun 옵션을 이용해 동작 수행만 하고 실제로 적용이 되지 않게 할 수 있다.
실수로 파일을 삭제해 난감해지는 일을 방지하기 위해 명령을 사전에 테스트할 목적으로 사용된다.
# 결과 출력 시, dryrun임을 표시하여 실제로 수행되지 않았음을 알려준다.
$ aws s3 rm s3://test-bucket-inpa/folder1/ --dryrun
(dryrun) delete: s3://test-bucket-inpa/folder1/
S3 권한 커맨드
파일에 권한 주기 (--acl)
콘솔 브라우저에서 일일히 객체를 클릭하여 권한을 설정하지말고 명령어로 간단하게 처리해보자.
Amazon S3는 미리 준비된 ACL이라고 하는 미리 정의된 권한 부여 세트를 지원한다.
이를 이용해 객체에 권한을 설정해보자.
$ aws s3 sync [이전 s3버킷 주소] [이전할 s3 버킷 주소] --acl public-read
ACL 옵션 | 설명 |
private | 아무도 액세스 할수 없음 (default) |
public-read | READ 액세스 |
public-read-write | READ, WRITE 액세스 |
$ aws s3 cp pass.copy s3://test-bucket-inpa --acl public-read
upload: ./pass.copy to s3://test-bucket-inpa/pass.copy
이렇게 명령어를 칠 경우 이전주소에서 이후 주소로 복사를 하게되고 public-read 권한을 주게 된다.
그리고 객체 URL로 접속해보면 권한 경고 없이 바로 접속됨을 확인 할 수 있다.
파일에 권한 주기 (--grants)
개체에 대한 권한을 부여하는 데 사용할 수 있는 --grants 옵션도 존재한다.
--grants Permission=Grantee_Type=Grantee_ID
- Permission : 권한 지정 (read, readacl, writeacl, full)
- Grantee_Type : 피부여자를 식별하는 방법을 지정 (uri, emailaddress, id)
- Grantee_ID : Grantee_Type에 따라 피부여자를 지정 (uri, emailaddress, id)
# 모든 사람이 읽을수 있게 권한을 부여하고 업로드
aws s3 cp filename s3://bucket/folder/filename --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers
S3 커맨드 응용하기
S3 특정 파일을 얻어서 다운받기 (루프문)
# 버킷 목록을 가져와서 날짜별로 sort하고
# awk 명령어로, 첫번째 필드($1)가 2021-01-20 날짜 이상일경우 and 네번째 필드($4)가 공백이 아닌경우,
# $4만 출력 (파일명 출려)
for f in $(aws s3 ls s3://bucket-name/ | sort | awk '$1 > "2021-01-20" && $4 > "" {print $4}'); do
aws s3 cp s3://bucat-name/"$f" ./ # 그리고 그 파일명으로 현재 디렉토리에 다운
done;
AWS S3 CLI 고급 명령어
aws s3 vs aws s3api
위에서 aws s3 커맨드를 통해 Amazon S3를 파일 시스템처럼 접근할 수 있었다.
반면에 aws s3api 커맨드를 통해서는 좀 더 Restful API 처럼 버킷에 접근할 수 있다.
즉, aws s3와 s3api 명령어의 차이는 s3의 명령어를 좀 더 추상화하여 쉽게 사용할 수 있게끔 만든 것 정도로 알아두면 된다.
# aws s3 명령어
$ aws s3 ls s3://test-bucket/css/
2018-06-09 20:08:24 121200 bootstrap.min.css
2018-06-09 20:08:24 542194 bootstrap.min.css.map
# aws s3api 명령어
$ aws s3api list-objects-v2 --bucket test-bucket --prefix css
{
"Contents": [
{
"Key": "css/bootstrap.min.css",
"LastModified": "2018-06-10T03:08:24.000Z",
"ETag": "\"ec3bb52a00e176a7181d454dffaea219\"",
"Size": 121200,
"StorageClass": "STANDARD",
"Owner": {
"DisplayName": "dale.seo",
"ID": "51dbe4e62e5471da8ee52476412bc9ad187d2a1c196ec9f937b3da7be3a18c70"
}
},
{
"Key": "css/bootstrap.min.css.map",
"LastModified": "2018-06-10T03:08:24.000Z",
"ETag": "\"35b79ebe0b7805c1c84524ad920faa33\"",
"Size": 542194,
"StorageClass": "STANDARD",
"Owner": {
"DisplayName": "dale.seo",
"ID": "51dbe4e62e5471da8ee52476412bc9ad187d2a1c196ec9f937b3da7be3a18c70"
}
}
]
}
s3api 커맨드
# 버킷 생성하기
aws s3api create-bucket \
--bucket cloudaffaire-s3-select-demo \
--region ap-south-1 \
--create-bucket-configuration LocationConstraint=ap-south-1
# 버킷의 Region 확인
$ aws s3api get-bucket-location --bucket [버킷명]
# 버킷의 객체를 모두 json으로 조회
$ aws s3api list-objects-v2 --bucket [버킷명]
# 객체의 메타데이터 확인
$ aws s3api head-object --bucket [버킷명] -key [fileName]
# 객체의 태그 조회
$ aws s3api get-object-tagging --bucket [버킷명] --key [fileName]
# 해당 버킷이 버저닝을 사용하는지 체크
$ aws s3api get-bucket-versioning --bucket [버킷명]
# 버킷의 버저닝된 객체 리스트를 출력
$ aws s3api list-object-versions --bucket [버킷명]
# 특정 객체를 다운로드
# [version id] : 위의 list-object-versions 명령어를 통해 가져온 id
# [outfileName] : 받은 객체를 어떤 이름으로 저장할지
$ aws s3api get-object --bucket [버킷명] --key [fileName] --version-id [version id] [outfileName]
S3 SELECT 커맨드
S3 Select는 SQL 문을 기반으로 S3 객체의 콘텐츠를 필터링하는 커맨드이다.
한마디로 S3의 데이터를 조회할때 SQL문으로 조회한다고 보면 된다.
이 S3 Select 요청에는 받기 원하는 데이터 포맷(JSON, CSV, or Apache Parquet)을 지정해야 한다.
S3 SELECT VS AWS Athena
S3 Select는 설계된 S3 기능중 하나이다.
전체 개체 대신 (단순 SQL 식을 사용하여) 개체의 데이터 하위 집합을 검색하여 작동한다.
s3 select는 s3 버킷에서 한 번에 단일 개체에 대해 쿼리를 실행한다.
반면 Amazon Athena는 표준 SQL을 사용하여 S3에 저장된 데이터를 쉽게 분석할 수 있는 아마존의 쿼리 서비스 이다.
Athena는 서버리스이므로 설정하거나 관리할 인프라가 없으며 쿼리에 대해서만 비용을 지불하는 식이다.
쿼리를 병렬로 실행하므로 대규모 데이터 세트와 복잡한 쿼리에서도 더 빠른 결과를 얻을 수 있다.
## Select CSV data using S3 select
$ aws s3api select-object-content \
--bucket cloudaffaire-s3-select-demo \
--key employees.csv \
--expression "select * from s3object limit 2" \
--expression-type 'SQL' \
--input-serialization '{"CSV": {}, "CompressionType": "NONE"}' \
--output-serialization '{"CSV": {}}' "csv_output.csv"
## Check the output
$ cat csv_output.csv
## You can also output CSV data in JSON format
$ aws s3api select-object-content \
--bucket cloudaffaire-s3-select-demo \
--key employees.csv \
--expression "select * from s3object limit 2" \
--expression-type 'SQL' \
--input-serialization '{"CSV": {}, "CompressionType": "NONE"}' \
--output-serialization '{"JSON": {}}' "csv_output.json"
## Check the output
$ cat csv_output.json
## Select JOSN data using S3 select
aws s3api select-object-content \
--bucket cloudaffaire-s3-select-demo \
--key employees.json \
--expression "select * from s3object limit 2" \
--expression-type 'SQL' \
--input-serialization '{"JSON": {"Type": "DOCUMENT"}, "CompressionType": "NONE"}' \
--output-serialization '{"JSON": {}}' "json_output.json"
## Check the output
$ cat json_output.json
버킷의 생명 주기 설정
Amazon S3에 저장되어 있는 파일들의 생명 주기 관리를 위해서 관련 AWS CLI 커맨드를 사용할 수 있다.
S3 Life Cycle에 대해서는 다음 포스팅을 참고하길 바란다.
버킷 생명 주기 등록
$ aws s3api put-bucket-lifecycle --bucket <버킷명> --lifecycle-configuration \\
'{ "Rules": [ { "Expiration": { "Days": 30 }, "ID": "Retention", "Filter": { "Prefix": "" }, "Status": "Enabled" } ] }'
버킷 생명 주기 확인
$ aws s3api get-bucket-lifecycle --bucket <버킷명>
버킷 생명 주기 삭제
$ aws s3api delete-bucket-lifecycle --bucket <버킷명>
객체 Presigned-URL 생성
# 특정 객체에 대한 Presigned URL을 생성
$ aws s3 presign s3://<bucket>/<fileName> --expires-in <원하는 시간 ms>
이 글이 좋으셨다면 구독 & 좋아요
여러분의 구독과 좋아요는
저자에게 큰 힘이 됩니다.