Study Notes - AWS S3
S3 全名是 Simple Storage Service
,故縮寫 S3,它是 AWS 在 2006 年推出的 第二個 SaaS 服務,有很長的歷史。雖然名字有個 Simple,但其實它不容易。本文整理研讀官方文件、以及工作上遇到的問題,整理以下的筆記:
- 一、基本概念 (Concepts)
- 二、核心功能 (Core Functions)
- 三、存取權限 (Access Control)
- 四、資料保護 (Data Protection)
- 五、服務限制 (Limitation)
- 六、開發 (Development)
- 七、成本 (Cost)
- 八、應用場景 (User Scenarios)
- 九、常見問答 (FAQ)
一、基本概念 (Concepts)
整理幾個 S3 的核心概念:
- Buckets
- Objects
- Keys
- Resions
- Data Consistency Model
Bucket
Bucket 中文可以翻譯成水桶、籃子,是容器 (Container) 的概念,也就是可以放東西的容器。
在 S3 裡的 Bucket 名稱是 唯一的
、而且是全域 (Global)、跨 Account、跨 Region 的,換言之,不管是哪一個 AWS 的使用者,Bucket Name 都不能與其他人重複。雖然 Bucket 名稱是唯一的識別,但是建立 Bucket 時要選擇 Region,表示實際上資料 Region Level 的,換言之,如果在乎存取的延遲時間,就要注意 Region 的位置。
Bucket Name 與 Static WebSite 的關係後面段落詳細說明。
Bucket 名稱的命名規則
底下是 AWS 官方建議的命名注意事項:
- 命名要符合 DNS 命名規範,例如不可以用底線 (
_
, underscore)、大寫字母 (uppercase, 2018/03 後)- 因為這名稱會被拿區當作 DNS 名稱,DNS 命名不允許有底線。
- 長度至少 3 個字元,最多 63 個字元
- 名稱開始要小寫字母或者數字
- 不要使用 IP address 當作名稱
- 名稱不要包含點
.
當作段落的切割字元。- 目前可以使用,沒有阻擋。
- 如果要使用 Transfer Acceleration,那 bucket name 不可以包含點
Bucket Name 命名建議格式:
{ACCOUNT_NAME}-{REGION}-{PURPOSE}
- 建議使用 AWS Account Name 做開頭,避免與其他使用者衝突。在 IAM 的首頁可以設定,這個名稱也被當來 IAM Login 的 URL,例如:
https://{AWS_ACCOUNT_NAME}.signin.aws.amazon.com/console
- 例如我的一個 AWS Account Name 叫做 gtlab01,那麼 bucket name 的開頭就是
gtlab01-us-west-2-s3-lab
,如此不會與其他人衝突,也可以區分不同 region 的 bucket。- 命名格式後面可以自行延伸,主要就是前置 (
{ACCOUNT_NAME}-{REGION}
) 與切割符號 (我使用-
) 要注意,後面可以延續其他實際的用途,像是環境、服務名稱 … etc.
Dual Stack (IPv6)
S3 Bucket 支援 IPv4 與 IPv6,DualStack 為了同時相容兩者,他們的 Endpoints 如下:
Path-style dual-stack endpoint:
s3.dualstack.{REGION}.amazonaws.com/{BUCKET_NAME}
Virtual hosted-style dual-stack endpoint:
{BUCKET_NAME}.s3.dualstack.{REGION}.amazonaws.com
相關文件:Amazon S3 Dual-Stack Endpoints
功能全貌
每個 Bucket 除了儲存的物件之外,都會有三大主要的功能區塊,展開有以下:
- Properties
- Versioning: 物件的版本管理
- Server Access Logging: 存取紀錄
- Staitc Website Hosting: 靜態資料網站
- Object-level Logging: 紀錄 API 存取的紀錄,主要配合 CloudTrail
- Default Encryption: 預設的加密方式
- Advanced: Object Lock、Tags、Transfer Acceleration、Events、Requester Pays … 等,後面分段描述。
- Permission: Block Public Access, Access Control List, Bucket Policy, CORS
- Management: Lifecycle、Replication、Analytics、Metric、Inventory
- Access points (2019)
詳細介紹整理在後面。
Objects
S3 是一個 Object Store,存放在 S3 Bucket 裡的東西都稱為 Object (物件)
,一個 Object 由以下組成:
- Key: 有時候會稱 Object Key、Key Name,在 Bucket 裡的唯一識別
- Version Id: 在 Bucket 裡,Key 和 Version ID 的組成,識別出一個 Object。S3 以此做到
Object Versioning
功能。 - Value: 就是實際儲存的資料內容。單一資料最大 5TB。
- Metadata: 是一個 Key-Value 的資料結構,儲存物件的控制資訊。分成
User-definied Metadata
、System-defined Metadata
兩大類。 - Subresources: 定義 Bucket 與 Object 關係的。
- Access Control Information
整理下圖描述整個 Object 的組成:
Object Keys
也稱做 Object Key、Key Name,在 Bucket 裡是唯一識別,由 (Prefix + Delimiter)
+ Key Name
組成。整理概念如下圖:
Prefix 可以想像成目錄 (Folder) 的概念,透過 Delimiter (/
) 隔開。以此規則,例如:
- Bucket Name: www.abc.com
- Key:
- dev/design.md
- dev/seq-flow.md
- marketing/rel/purchese.pdf
- index.html
這四個都是 Key,只是 index.html 沒有 prefix,其他則有。在 S3 Console 就會看到目錄的結構。
Version Id
S3 支援 Object 的版本管理,稱為 Versioning。每個物件都有屬於自己的 Version Id
用來區別版本。詳細後面描述。
Object Metadata
Object Metadata 由 Key-Value 組成的資料結構,分成兩個部分: System-defined Metadata (SDM)
、User-defined Metadata (UDM)
,整理概念如下圖:
SDM 主要是 S3 用來系統資訊和控制屬性的。系統資訊像是時間、日期、MD5 … 等;控制屬性像是 server-side encryption 的是否開啟、version-id、Storage Class。大概分成可以修改與不可以修改兩大部分。下圖摘自官方文件的詳細列表:
放一個 Object,並指定 UDM:
1 | aws s3api put-object \ |
取得 Object:
1 | aws s3api head-object \ |
User-defined Metadata 的資料會在 HTTP Header x-amz-meta-{UDM_NAME}
呈現,例如上述範例就會產生 x-amz-meta-version
這樣的 header.
Storage Classes
儲存在 S3 上的物件,依照使用情境與需求,分成幾種 儲存類型 (Storage Classes)
,這些類型也會反映在 SLA (可用性、持久性)
、成本
、效能
之上。下表是 官方文件 的提供的資訊:
Regions
建立 Bucket 的時候,除了名稱要考慮唯一性之外,也要選擇 Bucket 的位置。官方文件描述,只要物件存在 Region 之內,就不會再離開,除非使用者自行傳輸到其他地方。所以當應用程式需要考量傳輸效能時,在規劃 Bucket 時也要同時考慮地理位置,避免因為網路傳輸的問題,影響效能。
Data Consistency Model (資料一致性模式)
- 所有的 Region 的支援 PUTS and DELETES 操作的
最終一致性模型
- 寫入新的 Object 而且立刻 list bucket: 新的 Object 不會顯示在 list ,直到更改傳遞到所有的 servers
- PUTS:
read-after-write consistency
- PUTS:
- 更新既有的物件,同時立刻讀取:S3 可能會傳回前一個物件,直到更改傳遞到所有的 servers
- 刪除既有物件,同時立刻讀取:S3 可能回傳要刪除的物件,直到更改傳遞到所有的 servers
- 刪除既有物件,同時 list bucket 裡的 keys: S3 可能還是會顯示刪除的 object,直到更改傳遞到所有的 servers
- 目前 S3 不支援 Object Locking
下表描述 Eventually Consistent Read (最終一致性讀取)
& Consistent Read (一致性讀取)
的差異:
更多關於
最終一致性
的概念,參閱 Eventually Consistent 與 Dynamo NWR 模型
二、核心功能 (Core Functions)
S3 除了存資料之外,有很多因應而生的功能,這些功能都很實用,也是很多人選擇 S3 的主因。
以下整理一些我個人認為的核心功能,我把他們分成兩大類:
- 應用功能:應用服務使用的功能,主要是提供 Feature、創造價值,屬於進攻。
- 管理功能:維運管理功能,主要是針對資安、節省成本,屬於防守。
Static Website Hosting
有以下幾種方法可以讓 S3 當作靜態網頁服務:
- 使用 S3 Bucket 的 Static Website Hosting 功能 (沒有 HTTPS)
- 整合 Route 53 Alias + S3 Bucket (沒有 HTTPS)
- 整合 CloudFront + Route 53 Alias + S3 Bucket (有 HTTPS)
S3 Bucket + Route53
- 建立 S3 Bucket
- 使用 Domain Name 當作 S3 Bucket Name,例如:
website1.abc.com
,此例子放在us-west-2
- 開啟
Static Website Hosting
功能,一定要開啟,否則功能不會正常(如下訊息)。
- 權限:
- 關閉
Block public access
,預設是開啟的。因為太多資安事件,後來新增的預設功能。 - 用 Bucket Policy 或 Object ACL ,後面描述
- 放一個
index.html
- 使用 Domain Name 當作 S3 Bucket Name,例如:
- 設定 Route 53
- 新增一筆 A Record
- 開啟 Alias,選擇已經建立好的 S3 Bucket,或者填入:
s3-website-us-west-2.amazonaws.com.
。 如果 AutoComplete 沒有 S3 Bucket 可以選,表示沒有開啟Static Website Hosting
,如果已經開啟卻沒得選,重新載入 Route53 Console。如下圖:
- 權限設定:要讓使用者可以瀏覽靜態資料
Bucket Policy
:好處是 Object 上傳後,不需要額外的權限設定。底下是範例:1
2
3
4
5
6
7
8
9
10
11
12{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::website1.abc.com/*"
}
]
}Object ACL
:開啟個別 Object 的 Permission,方法有以下:- 在 S3 Console,選擇 Object -> “Make Public”
- 在 S3 Console:點選 Object -> 右邊 Properties -> Permission -> Public access -> 開啟
Read Object
- 透過 SDK / API 操作(如下),指定 ACL 為
public-read
1
2
3
4
5
6
7aws s3api put-object \
--acl public-read \
--body s3-permission-control-flow.png \
--bucket website1.abc.com \
--key images/s3-permission-control-flow.png \
--content-type image/png \
--content-disposition "inline; filename=s3-permission-control-flow.png"
權限兩種方法都可以,如果要安全性高一點,選擇 Object ACL 控制,透過程式控制;如果是開放資料,像是文件,則可以使用 Bucket Policy 控制。
Endpoints of Path-Style and Virtual-Hosted Style
S3 支援兩種存取格式的 Endpoints,格式如下:
Path-Style (v1)
:- Bucket in us-east-1:
https://s3.amazonaws.com/{BUCKET_NAME}/{OBJECT_KEY_NAME}
- Bucket in other regions:
https://s3-{REGION_CODE}.amazonaws.com/{BUCKET_NAME}/{OBJECT_KEY_NAME}
- Bucket in us-east-1:
Virtual-Hosted Style (v2)
- Bucket in us-east-1: 同下
- Bucket in other regions:
http://{BUCKET_NAME}.s3-website-{REGION_CODE}.amazonaws.com/{OBJECT_KEY_NAME}
為了方便說明,我建立兩個 Bucket 當範例:
- website.abc.com -> region 在 us-east-1 (N. Virginia)
- website1.abc.com -> region 在 us-west-2 (Oregon)
Path-Style 是第一代 (1) 的格式,選擇一個 Object,下圖是 Overview,這是放在 Virginia 的 Object URL:
下圖是放在 Oregon 的 Object URL,有包含 REGION_CODE: us-west-2
不難發現,Path-Style
就是以 Region 為主要的 Hostname,然後把 Bucket Name 當作 URL 路徑看待,而且支援 HTTPS。另外 Virginia 因為是第一個 region,所以預設的 S3 Domain Name 就是給他用,其他則有個別的 Domain Name.
Virtual-Hosted Style 是第二代 (v2) 的格式,主要就是以 Bucket Name 作為 Hostname。同樣的用 us-east-1、us-west-2 做範例,如下圖,在 Bucket -> Properties -> Static Website Hosting 找存取的 Endpoint:
要注意的是:
- Path-Style 支援 HTTPS
- Virtual-Hosted Style:
- 如果 Bucket Name 有
. (dot)
出現,那就無法支援 HTTPS,需要依賴 CloudFront - 如果 Bucket Name 沒有
. (dot)
,那可以支援 HTTPS
- 如果 Bucket Name 有
相關新聞:
- 2019/05/08: Amazon S3 Path Deprecation Plan – The Rest of the Story: 2020/09 將淘汰 Path-Style.
Event Notifications
S3 支援 Events 功能,屬於 Bucket Level 設定,透過 Notification 達到事件處理的功能。
每個 Event 由以下組成:
Name
: 顯示用名稱,不是 Key / Id,可以修改Event Types
: 分成 Create、Remove、Others 三大類Filter
: 依據 Prefix、Suffix 為過濾條件,例如prefix=images/
、suffix=jpg
PUT, prefix=images, suffix=jpg
和PUT, prefix=images/, suffix=txt
是不同的條件。- 注意 filter 條件不能重複
Destinations
: 處理,支援 SNS, SQS, Lambda
Events Types (Action) 包含以下:
- Create an object:
- s3:ObjectCreated:*
- s3:ObjectCreated:Put|Post|Copy|CompleteMultipartUpload
- 如果上傳失敗,不會收到 failed operation
- Remove an object:
- s3:ObjectRemoved:*
- s3:ObjectRemoved:Delete|DeleteMarkerCreated
- 透過 lifecycle 刪除,或者刪除失敗不會收到 failed operation
- Others:
- restore objects: s3:ObjectRestore:Post, s3:ObjectRestore:Completed
- s3:ReducedRedundancyLostObject
設定好 Event 之後, 觸發後 S3 會送出這樣的 Message:
1 | { |
問題:
Q: 同一個 Event,支援同時多種 Destinations?
問題可以改成同一個 Event 的 Filter,可否支援多個 Dest?透過 SNS 就可以做到,也就是 Pub/Sub Fanout 的功能。。
Q: 同一個檔案,重複 Put,S3 會發 Event?
實測過:會。
Q: 刪除不存在的 Object,會重複驅動 Event?
實測過:不管有無開啟 Versioning 都會收到 Event,只是 EventName 會有所差異:
ObjectRemoved:Delete
、ObjectRemoved:DeleteMarkerCreated
。
Q: 如果擔心 S3 Event 有遺漏,該如何確認?
依照官方文件,以及實測的經驗,遺漏的機率很小,但如果真的需要檢驗方式,可以透過 Inventory 功能。假設上傳後儲存到 S3 沒問題,問題會發生的是在 S3 發動 Event 這個過程。相關文件:
Q: 能否控制 S3 發送 Event 的速率?
目前只能透過 Lambda Concurrency 控制。實測以下的狀況:
- Lambda Concurrency=3
- 短時間 (< 5m) 之內,上傳約 1300 個圖檔
觀察 LambdaConcurrentExecutions
的狀況,以及Invocations
的總和
Q: Lifecycle 刪除的檔案會發動 Event?
不會。
Q: 哪裡可以監控 Event 發動的狀況?
目前只能從 Destination 端的 Metric 監看,像是 Lambda 的 Invocations、SQS 的 Invocations、SNS 的 NumberOfMessagesPublished 等。
Q: Event 是發生在 S3 Action 前、還是後?
我也想知道。
Lifecycle Management
Bucket Level 的功能,主要用途是透過 條件
+ 轉換
+ 過期
- 條件 (Rule):Prefix 或者 Tags
- 轉換 (Transition):
- 針對目前的版本或者前一些版本
- 在 n 天之後,把 Object 轉換成指定的 Object Class
- 過期 (Expiration):
- 針對目前的版本或者前一些版本
- 在 n 天之後完全刪除,或者把 MarkDelete 的刪除
- 刪除未完成的 multipart upload
是非常實用的維運功能,經常使用的就是
- 刪除 n 天之前的備份資料
- 把轉換 n 天之前 Object 放到 Gliacier (磁帶)
Monitoring
監控 S3 的方法有很多,主要還是以 CloudWatch 為主。在 Bucket Level 的設定 -> Management -> Metrics 直接把 CloudWatch Metric 整合了。分成 Storage、Request、Data Transfer 三大部分。其中 Storage 預設是開啟的,Requests、Data Transfer 是另外要付費的。
另外可以透過 Filter 的方式,針對 Prefix、Tags 過濾想要監控的資訊。
除了 CloudWatch 的監控,AWS 還有其他服務可以做更細緻的監控,列舉如下:
- S3 Server Access Logs:S3 自身的 Access Logs。
- Trusted Advisor:成本、資安
- AWS Config Rules:程式化、自動化
- Amazon Macie:機器學習的安全服務,可以找到敏感資料、個資 … 等。
- CloudTrail:AWS 本身的 Audit Log
Others
其他本文尚未整理的功能。
- Analytics: Data Lake (Athena, Redshift, QuickSight), IoT Streaming Data, Machine Learning and AI Storage, Storage Class Analysis
- Access Log
- Cross-Region Replication
- Tags
- Batch
- Transfer Acceleration: Spped up data uploads using CloudFront in reverse.
- BitTorrent
三、存取權限 (Access Control)
S3 存取的授權方式有兩種:Resource-based policies
和 User Policies
。底下整理自 Overview of Managing Access。
Resource-based Policies
概念如下圖 (取自 官方文件),分成針對 Bucket 的 Bucket Policy
、Bucket ACL
,以及針對 S3 Object 的 Object ACLs
:
Bucket ACLs / Object ACLs
: 每個 Bucket 和 Object 都有一個 ACL 的關聯。ACLs 用來針對特定 識別
發放權限。像是可以發放給另一個 AWS Account 權限。可以透過設定 Account Canonical User ID
,讓另一個帳號可以存取 Bucket(但是不會在 Bucket List 上出現)。可設定的資訊如下:
Canonical User ID
: 是個 Long String,大概像這樣:7ae3d7f85d42d21d250ff1c13b3b8ec92189bedbd648252984ba6526a3b071d1
,可以在 S3 Bucket ACL 裡找到。Bucket ACLs
:- List Objects、Write Objects、Read Bucket Permissions、Write Bucket Permissions
Object ACLS
:- Read Objects、Read Object Permissions、Write Object Permissions
- 注意:沒有 Write Objects
Bucket ACLs 以 XML 呈現,新版的 S3 Console 透過 GUI 設定即可。舊版的 Console 則需要自行設定 XML,格式如下:
1 |
|
Bucket Policy
: 主要發放權限給 AWS Account 或者 IAM Users,整個 Bucket 與 Object 都會應用 Policy。Policy 的設定同 IAM Policy 的設計,每個 Statement 主要有必要的 Effect、Principal、Action、Resource 以及選擇性的 Condition。
Principal 用來授權給哪一個 AWS Account 或者 特定的 Canonical User ID。AWS Account 使用的就是 ARN 格式,例如:
1 | "Principal": { |
Canonical User ID 範例:
1 | "Principal": { |
Condition 通常用來篩選條件,像是控制來源 IP、特定的 http header … etc。底下範例是授權特定來源 IP 存取的範例:
1 | { |
User policy
這個 User
指的是 AWS IAM,包含 IAM users、groups、roles,概念如 官方文件 的圖:
IAM 相關概念請參閱 Study Notes - Identity and Access Management (IAM) 的整理
S3 如何處理授權請求?
官方文件: How Amazon S3 Authorizes a Request 針對 Bucket Operation 和 Object Operation 有兩張圖,比較複雜,下圖是我自己簡化的整理。主要以 IAM User 的角度出發,分成三個驗證步驟:
- 確認是否符合 Bucket ACL,主要確認是不是 CanonicalUser
- 是否符合 Bucket Policy 的條件,預設 Bucket Policy 是空的。
- 如果 2) 不符合,那麼看看是否符合 IAM Policy
四、資料保護 (Data Protection)
資料保護分成資料加密 (Data Encryption) 以及版本控管 (Versioning) 討論。
Data Encryption (At Rest)
S3 的資料加密分成以下種:
Server-Side Encryption (SSE)
: 由 Server-Side 負責加密後寫入儲存體,加密過程的運算資源、加密演算法都由 Server-Side 提供。- SSE-S3:全名是
Server-Side Encryption with Amazon S3-Managed Keys
。加密過程使用的 Data Key 與 Master Key 都由 S3 管理,不需要自行管理,Master Key 則會定期更新 (Rotation)。S3 使用 256-bit Advanced Encryption Standard (AES-256) 加密。 - SSE-KMS:顧名思義就是使用 KMS 的 CMKs (Customer Master Keys) 加密 S3 Object。KMS 會負責管理 Data Key。
- SSE-C: 全名是
Server-Side Encryption with Customer-Provided Keys
,由使用者提供 Encryption Key 作加密。
- SSE-S3:全名是
Client-Side Encryption (CSE)
:- Client-Side (PGP, GPG)
以下整理 SSE 三種的差異:
更多關於參閱:密碼學與資訊安全 的整理
Versioning
S3 Bucket Level 支援版本管控,亦即每個物件都可以有版本的概念。S3 Object 由 Key + VersionId + Metadata + Value 組成。其中 VersionId 就是用來代表版本概念的關鍵屬性。
做了實驗:
- 上傳一個檔案
- 同一個檔案,再上傳一次
- 刪除檔案
- 同一個檔案,再上傳一次
1 | FILENAME="IMG_0001.JPG" |
結果如下圖:
觀察到的現象:
- S3 不會比對檔案來源,同樣的檔案會產生不同的 VersionId
- 被蓋過去的檔案,可以下載
Q: 如何指定特定的 VersionId 為 Latest Version?
目前的方法只能指定 VersionId ,然後重新上傳該物件,把物件改掉。
Q: 被標記 Delete Marker 可以下載?
實測結果不行。
五、服務限制 (Limitiation)
Bucket Restrictions and Limitation
- Bucket:
- 每個 AWS 帳號可以建立 100 buckets,可以透過 Support Ticket 增加上限,最多可以到 1000 個。
- bucket ownership is not tranferable.
- delete bucket, the name become available.
- bucket policy size: 20KB, see: https://docs.aws.amazon.com/AmazonS3/latest/dev/example-bucket-policies.html
六、開發 (Development)
S3 每個 bucekt 除了提供 static website hosting 的功能,也提供了 REST API 給開發者使用。REST API for bucket 規則如下:
- Path-Style:
- us-east-1:
https://s3.amazonaws.com/{BUCKET_NAME}/
- other regions:
https://s3-{REGION_CODE}.amazonaws.com/{BUCKET_NAME}/
- us-east-1:
- Virtual-Hosted Style:
https://{BUCKET_NAME}.s3-{REGION_CODE}.amazonaws.com
- 要注意的是,名字不是
s3-website-{REGION_CODE}
- 要注意的是,名字不是
權限的設定如下:
- 關掉
Block Public Access
- 開啟 Bucket ACL 的 List Object
不需要開啟 Static Website Hosting
例如 bucket name 叫做 website.abc.com
,那就可以透過 https://website.abc.com.s3-us-west2.amazonaws.com
存取,下圖是 Path-Style 和 Virtual-Hosted Style 的範例:
七、成本 (Cost)
S3 的成本分成幾個部分:儲存費用、請求費用、資料傳輸、S3 Transfer Acceleration、跨區複寫
儲存費用
Storage Classes: 依照儲存的類型,有不同的成本價錢,不同 region 也會有不同的定價。底下以 Oregon 做範例整理。下圖是 S3 Standard Class 的價錢,分成三個區段:
下圖是其他 Storage Classes 比較表:
下圖各種 Storage Classes 成本比例分析表:
請求成本
依照 REST 的請求,以及資料傳輸,費用會有所差異。計費考量的面相有以下:
- 操作:PUT、COPY、POST、GET、SELECT 請求,其中 DELETE、CANCEL 是不用費用的。
- 透過 S3 功能 (Select) 取得的資料傳輸費用
依照 Storage Classes,分成不同價錢,傳輸的資料也有不同價錢。
八、應用場景 (User Scenarios)
應用場景我分成兩大類:解決方案、功能特性。解決方案通常會整合其他 AWS Services,整體也比較複雜;功能特性會著重在 S3 自身的功能應用。
- 功能特性
- 大量上傳
- Pre-signed URL
- 在 EC2 使用 S3 當作延伸磁碟
- 如何跨帳號存取 S3 Bucket
- 解決方案 (Solution)
- 靜態資料傳遞:搭配 CloudFront
- 非同步批次處理:搭配 Lambda
- Log 儲存與分析:搭配 Kinesis Firehose、Athena
- 跨區資料備份與同步
跨帳號存取 S3 Bucket
AWS Account A 有一個 Bucket 叫做: Acc-A-Bucket1
,AWS Account B 有個 User 叫做 user1,想要存取此 Bucket。
- 取得 Account B 的
Canonical User Id
,然後到Acc-A-Bucket1
Permissions -> ACLs -> Access for other AWS accounts,加入 CU ID. - 驗證:使用 user1 的 profile 下 CLI
1
2
3
4
5
6
7
8
9
10
11
12## List Bucket and Object
~$ aws s3 ls s3://Acc-A-Bucket1/
2019-06-10 22:53:22 0
2019-06-10 22:53:52 38201 AccessControlAuthorizationFlowBucketResource.png
2019-06-10 22:53:52 50491 AccessControlAuthorizationFlowObjectResource.png
2019-06-10 22:53:58 1410705 Amazon-S3.png
2019-06-10 22:53:52 23472 resource-based-policy.png
2019-06-10 22:53:51 18793 user-policy.png
## 複製檔案:無法存取
~$ aws s3 cp s3://Acc-A-Bucket1/user-policy.png .
fatal error: An error occurred (403) when calling the HeadObject operation: Forbidden - 設定
Acc-A-Bucket1
的 Bucket Policy,如下:1
2
3
4
5
6
7
8
9
10
11
12
13{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::1234567890123:user/user1"
},
"Action": "s3:*",
"Resource": "arn:aws:s3:::Acc-A-Bucket1/*"
}
]
} - 驗證:使用 user1 的 profile 下 CLI:
1
2~$ aws s3 cp s3://Acc-A-Bucket1/user-policy.png .
download: s3://Acc-A-Bucket1/user-policy.png to ./user-policy.png
結論:
- 跨帳號授權,必須在目標 Bucket 上設定同時 ACL 與 Bukcet Policy
- 原 IAM USer 的 IAM Policy 不需要額外設定權限。
在 EC2 使用 S3 當作延伸磁碟
這是很多人一開用 S3 想到的,底下整理著名的工具:
- https://github.com/s3fs-fuse/s3fs-fuse
- https://github.com/kahing/goofys
- https://github.com/danilop/yas3fs
剛開始用 S3 就用找過類似的,但因為 S3 的資料模型關係,往往使用體驗不如預期,所以大部分我不會建議這樣使用。
Bucket List
有時候需要提供列出檔案下載的功能,類似於 Apache Index,可以利用 Bucket ACL + CORS 達到此功能。設定如下:
- 設定 Bucket ACL,允許 Read Object
- 設定 CORS 如下:
1
2
3
4
5
6
7
8
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>*</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration> - 開啟 Static Website Hosting
- 開啟 ACL,允許 ListObject
- 這個方法使用 S3 SOAP 方式取的 Bucket List
- 下載:
https://github.com/rufuspollock/s3-bucket-listing
,設定index.html
如下:1
2
3
4
5<script type="text/javascript">
var S3BL_IGNORE_PATH = true;
var BUCKET_URL = 'https://{BUCKET_NAME}.s3-{REGION_CODE}.amazonaws.com';
</script>
<script src="/list.js"></script> - 瀏覽網站,可以看到如下畫面:
九、常見問答 (FAQ)
Q: 使用 S3 當靜態網站,能支援 HTTPS?
目前 S3 website endpoint 不支援 HTTPS,通常會搭配 CloudFront + ACM。參見 Website Endpoints
Q: 一個 S3 Bucket 有哪一些 Endpoints?
S3 的幾種 Endpoints 規則,分四大類,各有其用途:
- Static Web Host:
{BUCKET_NAME}.s3-website-{REGION}.amazonaws.com
- Path-Style, 又稱 v1
- IPv4
- us-east-1:
s3.amazonaws.com/{BUCKET_NAME}/
- other regions:
s3-{REGION_CODE}.amazonaws.com/{BUCKET_NAME}/
- DualStack (IPv6):
s3.dualstack.{REGION}.amazonaws.com/{BUCKET_NAME}
- Virtual-Hosted Style, 又稱 v2
- HTTP:
{BUCKET_NAME}.s3-{REGION_CODE}.amazonaws.com
- 要注意的是,名字不是
s3-website-{REGION_CODE}
- 不支援 HTTPS
- DualStack (IPv6):
{BUCKET_NAME}.s3.dualstack.{REGION}.amazonaws.com
- HTTP:
- Web Service (SOAP):
{BUCKET_NAME}.s3-{REGION}.amazonaws.com
:- 透過 ACL 控制的 API Endpoint
Q: 使用 S3 當靜態網站,能限定來源 IP?或者特定 VPC?
可以,Bucket Policy 範例參閱: Example Bucket Policies for VPC Endpoints for Amazon S3
Q: S3 可以當 SFTP 站嗎?
自幹可以用 s3fs-fuse mount s3 bucket,然後開 ftp server,也可以直接用 AWS 的 Transfer for SFTP Service,好處不用開機器、直接用 S3,不過有點貴就是了。
Q: S3 的授權有分 Resource-based Policy 和 User Policies,應該使用哪一種存取方法?
好問題,AWS re:Invent 2018: Deep Dive on Amazon S3 Security and Management 有回答這問題,截圖如下:
Q: 如果沒有給 IAM Policy 的權限,但有 Bucket Policy,那麼同一個 Account 底下的 IAM User 可以存取 Bucket?
可以。底下是一個 Bucket Policy 範例:
1 | { |
Q: CloudFront 與 S3 整合的時候,需要開啟 Static Website Hosting?
不用打開 Static Website Hosting,而是使用 Object ACL 或者 Bucket Policy,如下:
- Object ACL: 每個物件 ACL 都要是
Public Read
- Bucket Policy: 允許
GetObject
這兩種選一種就好,然後
Block public access
要關掉。Bucket Policy 範例如下:
1 | { |
Q: S3 Bucket 做 Static Web Hosting,可否限制特定網站存取?
可以。確認 Browser 送出的 Request 會包含 http referer,然後透過 Bucket Policy 的
Condition
,限制 Referer 的 Domain Name 即可,底下範例是首頁放在 bucket www.abc.com,圖檔放在 bucket image.abc.com,這個 Bucket Policy 設定在 image.abc.com:
1 | { |
Q: AWS CLI 提供 s3 和 s3api,這兩個有什麼差別?
s3 是 high-level commands,s3api 則是 low-level commands,差異就是可控性。想要控制細緻的參數,像是 max_concurrent_requests、max_queue_size、max_bandwidth、multipart_threshold … 等效能的調教與除錯,那麼就要使用 s3api,詳細的配置參閱 AWS CLI S3 Configuration。
Q: Virtual-Hosted Style 提到 S3 Bucket Name 會變成 Hostname,如果名稱有很多點 .
會不會有問題?
實測 bucket name:
a.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9.0.1
,長度 63,結果是可以運行的,如下圖。依據 wikipeida 上對 DNS 的描述,節點數最多可以到 127 個,但是這個規範並沒有被定義在 RFC 裡。
Q: 有一些 AWS 服務建立的 Bucket (elasticbeanstalk-ap-northeast-1-{AWS_ACCOUNT_ID}) 無法刪除,可以刪?
找到 Bucket Policy,應該會看到類似以下的 Policy,刪除即可。
1 | { |
結語
越是有歷史的,表面看起來越是簡單的,背後越是有學問。AWS 每年 reInvent 都增加很多新服務,幾年下來數量翻倍的成長,但是實際上,還是圍繞在核心服務的所組合出來的應用架構。核心服務像是 EC2、S3、SQS、VPC、EBS、RDS、API Gateway、CloudFront、ELB、DynamoDB、CloudWatch、AutoScaling … 這些構成了整個 AWS 服務的生態系。深度的學好這些基礎服務的概念,對於學習其他服務會很有幫助。
延伸閱讀
站內延伸
- Study Notes - KMS
- Study Notes - Identity and Access Management (IAM)
- Eventually Consistent 與 Dynamo NWR 模型
- 摘要密碼學與資訊安全
官方文件
- Amazon S3 Developer Guide
- Working with Amazon S3 Buckets
- Amazon S3 REST API Introduction
- Overview of Managing Access
- How Amazon S3 Authorizes a Request
- Amazon S3 Path Deprecation Plan – The Rest of the Story
- AWS CLI S3 Configuration
Deep Dive and Whitepapers
- AWS re:Invent
- Whitepapers
- AWS Storage Services Overview, Dec 2016
- Encrypting Data at Rest, Nov 2014
- Amazon Web Services: Overview of Security Processes, May 2017
S3 新功能 (New Feature)
- 2019/04/30: Amazon S3 Introduces S3 Batch Operations for Object Management
- 2018/12/04: Amazon S3 Inventory adds Apache Parquet output format
- 2018/11/27: AWS Announces Amazon S3 Object Lock in all AWS Regions
- 2018/11/26: Announcing S3 Intelligent-Tiering — a New Amazon S3 Storage Class
- 2018/11/15: Introducing Amazon S3 Block Public Access – another layer of protection for your accounts and buckets
- 2018/09/05: Amazon S3 Announces New Features for S3 Select
- 2018/08/08: Amazon VPC Flow Logs can now be delivered to S3
- 2018/07/18: Amazon S3 Announces Increased Request Rate Performance
- 2018/04/30: Amazon S3 Adds Support for Amazon Glacier and S3 One Zone-Infrequent Access to Amazon CloudWatch Storage Metrics
- 2018/04/05: Amazon S3 Select Is Now Generally Available
- 2018/04/05: Announcing S3 One Zone-Infrequent Access, a New Amazon S3 Storage Class
更新紀錄
- 2017/09/03: 更新 S3 + CloudFront 整合
- 2019/06/11: 重構文章結構,分成數個部分。
- 2019/12/13: 加入一個 QA: S3 Endpoints 的種類