返回文章列表

S3 Route53 CloudFront 網站託管設定

本文介紹如何使用 AWS S3、Route53 和 CloudFront 進行網站託管,包含設定 S3 靜態網站、使用 CloudFront 進行內容傳遞、設定 Route53 DNS,以及使用 CloudFormation 佈署和設定 SSL/TLS 憑證,確保網站安全地透過 HTTPS 提供服務。

網頁開發 雲端服務

在 AWS 環境下,網站託管可以透過 S3、Route53 和 CloudFront 的整合來實作。首先,將靜態網站內容儲存於 S3 儲存桶中,並設定適當的儲存桶政策。接著,使用 CloudFront 作為內容傳遞網路 (CDN),提升網站效能和可用性。最後,透過 Route53 設定 DNS,將網域名稱指向 CloudFront 分佈,讓使用者可以透過自訂網域名稱存取網站。為了確保網站安全,我們可以使用 AWS Certificate Manager (ACM) 申請 SSL/TLS 憑證,並將其設定於 CloudFront 分佈上,讓網站可以透過 HTTPS 提供服務。此外,本文也示範如何使用 CloudFormation 以程式碼化的方式自動化佈署和設定這些資源,簡化網站託管的流程並提高效率。

使用 S3、Route53 和 CloudFront 進行網站託管

介紹

本章節將介紹如何使用 Amazon S3、Route53 和 CloudFront 進行網站託管。我們將探討如何設定 S3 靜態網站、如何使用 CloudFront 進行內容傳遞,以及如何使用 Route53 進行 DNS 設定。

使用 S3 進行靜態網站託管

設定 S3 靜態網站

要使用 S3 進行靜態網站託管,首先需要建立一個 S3 儲存桶,並將其設定為靜態網站。儲存桶的名稱必須與網域名稱完全相符,例如 qnatime.com

新增檔案和儲存桶政策

新增 index.htmlerror.html 檔案到儲存桶中,並新增一個儲存桶政策,允許所有人讀取儲存桶中的內容。

設定 Route53

在 Route53 中建立別名記錄,將網域名稱指向 S3 儲存桶。

程式碼範例

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "PublicReadGetObject",
      "Effect": "Allow",
      "Principal": "*",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::qnatime.com/*"
    }
  ]
}

內容解密:

上述程式碼範例是一個 S3 儲存桶政策,允許所有人讀取儲存桶中的物件。其中,Version 指定了政策的版本,Statement 指定了政策的陳述式。Sid 是陳述式的 ID,Effect 指定了陳述式的作用(允許或拒絕),Principal 指定了陳述式的主體(誰可以執行此動作),Action 指定了陳述式的動作(讀取物件),Resource 指定了陳述式的資源(儲存桶中的物件)。

使用 CloudFront 進行內容傳遞

建立 CloudFront 分佈

要使用 CloudFront 進行內容傳遞,首先需要建立一個 CloudFront 分佈。在建立分佈時,需要指定來源(S3 儲存桶)和別名(網域名稱)。

設定別名和預設根物件

在 CloudFront 分佈中設定別名和預設根物件。別名是指向 CloudFront 分佈的網域名稱,預設根物件是指當使用者存取網域名稱時,CloudFront 傳遞的預設物件。

程式碼範例

{
  "CallerReference": "qnatime-distribution-2019-01-12-07-45",
  "Aliases": {
    "Quantity": 2,
    "Items": ["qnatime.net", "www.qnatime.net"]
  },
  "DefaultRootObject": "index.html",
  "Origins": {
    "Quantity": 1,
    "Items": [
      {
        "Id": "my-origin",
        "DomainName": "qnatime.com.s3.amazonaws.com",
        "S3OriginConfig": {
          "OriginAccessIdentity": ""
        }
      }
    ]
  }
}

內容解密:

上述程式碼範例是一個 CloudFront 分佈設定檔。其中,CallerReference 指定了分佈的參考 ID,Aliases 指定了分佈的別名,DefaultRootObject 指定了預設根物件,Origins 指定了分佈的來源(S3 儲存桶)。

使用 Route53 進行 DNS 設定

建立別名記錄

在 Route53 中建立別名記錄,將網域名稱指向 CloudFront 分佈。

程式碼範例

{
  "Comment": "change batch request for qnatime.net",
  "Changes": [
    {
      "Action": "CREATE",
      "ResourceRecordSet": {
        "Name": "qnatime.net",
        "Type": "A",
        "AliasTarget": {
          "HostedZoneId": "Z2FDTNDATAQYW2",
          "DNSName": "d1obzjrl8ac1no.cloudfront.net",
          "EvaluateTargetHealth": false
        }
      }
    }
  ]
}

內容解密:

上述程式碼範例是一個 Route53 變更請求檔。其中,Comment 指定了變更請求的註解,Changes 指定了變更請求的內容。Action 指定了變更請求的動作(建立或刪除),ResourceRecordSet 指定了變更請求的資源記錄集。Name 指定了記錄集的名稱,Type 指定了記錄集的型別,AliasTarget 指定了記錄集的別名目標。

使用 S3、Route53 和 CloudFront 進行網頁託管的 CloudFormation 設定

本章節將詳細介紹如何使用 AWS CloudFormation 來設定 CloudFront 分發(Distribution)以及 Route53 的 RecordSet,以實作網頁託管。

CloudFront 分發堆積疊(Distribution Stack)的建立

首先,我們需要準備一個 CloudFormation 範本,該範本包含以下幾個主要部分:

  1. 範本版本和描述:首先定義範本的版本和描述(可選)。

  2. 引數(Parameters):定義一個引數區段,用於接受以逗號分隔的網域名稱別名列表。

    Parameters:
      DomainNameAliases:
        Description: 網站的網域名稱別名(例如:quizzercloud.com, www.quizzercloud.com)
        Type: CommaDelimitedList
    
  3. 資源(Resources):在資源區段中,我們定義 CloudFront 分發。

    Resources:
      MyCloudFrontDistribution:
        Type: AWS::CloudFront::Distribution
        Properties:
          DistributionConfig:
            Origins:
              - DomainName: quizzer.cloud.s3.amazonaws.com
                Id: myS3Origin
                S3OriginConfig:
                  OriginAccessIdentity: ''
            Enabled: 'true'
            Comment: '具有網域的 CloudFront 分發'
            DefaultRootObject: index.html
            Aliases: !Ref DomainNameAliases
            DefaultCacheBehavior:
              TargetOriginId: myS3Origin
              ForwardedValues:
                QueryString: 'false'
                Cookies:
                  Forward: none
              ViewerProtocolPolicy: allow-all
    
  4. 輸出(Outputs):建立一個輸出區段,以傳回 CloudFront 分發 ID 和網域名稱。同時,我們也會匯出網域名稱,以便稍後在 RecordSet 堆積疊中使用。

    Outputs:
      CloudFrontDistributionId:
        Value: !Ref MyCloudFrontDistribution
        Description: 'CloudFront 分發 ID'
      CloudFrontDomain:
        Value: !GetAtt MyCloudFrontDistribution.DomainName
        Description: 'CloudFront 分發網域名稱'
        Export:
          Name: CloudFrontDomainName
    

接著,我們需要建立一個 JSON 檔案來傳遞引數值給 aws cloudformation create-stack 命令,然後執行該命令來建立堆積疊。

RecordSet 堆積疊的建立

RecordSet 堆積疊用於在 Route53 中建立記錄集。範本如下:

  1. 引數定義:定義根網域名稱、子網域名稱和 S3 託管區域 ID 的引數。

  2. 資源定義:建立一個 AWS::Route53::RecordSetGroup 型別的資源,為網域新增 A 記錄。

    Resources:
      QuizzerCloudDNS:
        Type: AWS::Route53::RecordSetGroup
        Properties:
          HostedZoneName: !Sub
            - ${DomainName}.
            - DomainName: !Ref RootDomainName
          Comment: Zone apex alias.
          RecordSets:
            -
              Name: !Ref RootDomainName
              Type: A
              AliasTarget:
                HostedZoneId: !Ref RecordHostedZoneId
                DNSName: !ImportValue CloudFrontDomainName
            -
              Name: !Ref SubDomainName
              Type: A
              AliasTarget:
                HostedZoneId: !Ref RecordHostedZoneId
                DNSName: !ImportValue CloudFrontDomainName
    

內容解密:

  • HostedZoneName 指定了託管區域的名稱,後面跟著一個點(.)。
  • RecordHostedZoneId 是 CloudFront 分發的託管區域 ID,這是一個固定值。
  1. 輸出定義(可選):定義輸出區段以傳回 URL。

執行 aws cloudformation create-stack 命令,並傳遞必要的引數,然後使用 describe-stacks 子命令檢查狀態。

使用 HTTPS 保護網域 URL

在實際應用中,應該盡量使用 HTTPS 而不是 HTTP。由於目前尚未組態有效的證書,直接存取 HTTPS 網址會顯示「Not Secure」警告。下一章節將介紹如何建立和匯入有效的證書來解決這個問題。

停用和刪除 CloudFront 分發

要刪除 CloudFront 分發,首先需要停用它。停用分發需要使用 update-distribution 命令,並指定一個包含所有現有屬性的分發組態 JSON 檔案,但需將 Enabled 設定為 false

程式碼範例:

aws cloudfront get-distribution-config --id <Distribution_ID> --output json > distribution-config.json
# 編輯 distribution-config.json,將 "Enabled" 改為 false
aws cloudfront update-distribution --id <Distribution_ID> --distribution-config file://distribution-config.json
aws cloudfront delete-distribution --id <Distribution_ID>

內容解密:

  1. 首先,使用 get-distribution-config 命令取得當前分發組態的 JSON 檔案。
  2. 編輯該 JSON 檔案,將 Enabled 的值改為 false,然後儲存。
  3. 使用 update-distribution 命令更新分發組態,指定編輯後的 JSON 檔案。
  4. 等待分發狀態變為 Disabled 後,即可使用 delete-distribution 命令刪除分發。

使用 S3、Route53 和 CloudFront 進行網頁託管的 SSL/TLS 設定

在前面的章節中,我們已經瞭解如何使用 Amazon S3、Amazon Route 53 和 Amazon CloudFront 來託管靜態網站。然而,當我們使用自訂網域名稱時,直接透過 HTTPS 存取網站會出現「Not Secure」警告。本章節將指導如何為 CloudFront 分佈設定 SSL/TLS 證書,以啟用 HTTPS 存取並自動將 HTTP 請求重新導向至 HTTPS。

準備工作

在開始之前,請確保您已經:

  1. 按照「Chapter 9, Serverless Architecture Patterns and Practices」中的「Creating SSL certificates with ACM」配方取得了 ACM(AWS Certificate Manager)SSL/TLS 證書。
  2. 熟悉前述章節中關於 S3、CloudFront 和 Route 53 的設定步驟。

使用 AWS CLI 指令為 CloudFront 分佈設定 SSL/TLS 證書

步驟一:取得 ACM SSL/TLS 證書 ARN

首先,您需要取得與您的網域名稱(例如 www.qnatime.net)相關聯的 ACM SSL/TLS 證書 ARN。

步驟二:更新 CloudFront 分佈設定

建立或更新 CloudFront 分佈的設定檔(JSON 格式),加入 ViewerCertificate 屬性,範例如下:

"ViewerCertificate": {
  "ACMCertificateArn": "arn:aws:acm:us-east-1:<account_id>:certificate/42b3ba99-66e9-4e71-8c1c-4239c1e81c84",
  "SSLSupportMethod": "sni-only",
  "MinimumProtocolVersion": "TLSv1.1_2016",
  "Certificate": "arn:aws:acm:us-east-1:<account_id>:certificate/42b3ba99-66e9-4e71-8c1c-4239c1e81c84",
  "CertificateSource": "acm"
}

#### 內容解密:

此段 JSON 設定用於指定 CloudFront 分佈所使用的 SSL/TLS 證書。其中:

  • ACMCertificateArn 指定了 ACM 中 SSL/TLS 證書的 ARN。
  • SSLSupportMethod 設定為 sni-only,表示 CloudFront 只會對支援 SNI(Server Name Identification)的客戶端提供 HTTPS 服務。
  • MinimumProtocolVersion 設定了最低的 TLS 版本,以確保安全性。
  • CertificateCertificateSource 進一步確認了證書來源和 ARN。

步驟三:更新或建立 CloudFront 分佈

使用更新後的設定檔來建立或更新 CloudFront 分佈。如果是新分佈,請記得在 Route 53 中建立別名記錄,指向新的 CloudFront 分佈網域名稱。

步驟四:驗證 HTTPS 連線

更新完成後,嘗試透過 HTTPS 存取您的網站網域名稱。您應該不再看到「Not Secure」警告。點選瀏覽器中的鎖定按鈕,可以檢視證書詳情。

使用 CloudFormation 範本為 CloudFront 分佈設定 SSL/TLS 證書

範本結構概述

您可以更新現有的 CloudFormation Stack 或建立新的 Stack。以下概述了範本的關鍵部分:

  1. 引數定義:接受逗號分隔的網域名稱別名和證書 ARN。
  2. 資源定義:在 DistributionConfig 中定義必要的屬性,包括 OriginsEnabledCommentDefaultRootObjectAliasesDefaultCacheBehaviorViewerCertificate
DistributionConfig:
  Origins:
    - DomainName: quizzer.cloud.s3.amazonaws.com
      Id: myS3Origin
      S3OriginConfig:
        OriginAccessIdentity: ''
  Enabled: 'true'
  Comment: 'CloudFront Distribution with Domain'
  DefaultRootObject: index.html
  Aliases: !Ref DomainNameAliases
  DefaultCacheBehavior:
    TargetOriginId: myS3Origin
    ForwardedValues:
      QueryString: 'false'
      Cookies:
        Forward: none
    ViewerProtocolPolicy: redirect-to-https
  ViewerCertificate:
    AcmCertificateArn: !Ref DomainNameCert
    SslSupportMethod: sni-only

#### 內容解密:

此段 CloudFormation 範本定義了 CloudFront 分佈的設定。其中:

  • ViewerCertificate 部分指定了 ACM 證書 ARN 和 SSL 支援方法。
  • ViewerProtocolPolicy 設定為 redirect-to-https,使得任何 HTTP 請求都會被重新導向至 HTTPS,傳回 HTTP 狀態碼 301(永久移動)。

重要步驟回顧

  1. 建立CloudFront分配:指定根網域、WWW子網域以及ACM憑證ARN。
  2. 建立A記錄:為根網域和WWW子網域建立A記錄,指向CloudFront分配。
  3. 測試網域:透過HTTPS存取根網域和WWW子網域,確認能夠安全地接收來自S3儲存桶的回應。

運作原理

  • CloudFront支援三種方式的SSL/TLS憑證:預設的CloudFront憑證、ACM憑證和IAM憑證。優先使用ACM憑證。
  • 伺服器名稱指示(SNI):允許多個憑證執行在單一IP上,提高了靈活性。