

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 將資料從 Amazon Redshift 叢集跨帳戶卸載至 Amazon S3
<a name="unload-data-from-amazon-redshift-cross-accounts-to-amazon-s3"></a>

*Andrew Kamel，Amazon Web Services*

## 總結
<a name="unload-data-from-amazon-redshift-cross-accounts-to-amazon-s3-summary"></a>

當您測試應用程式時，在測試環境中擁有生產資料會很有幫助。使用生產資料可讓您更準確地評估正在開發的應用程式。

此模式會將生產環境中 Amazon Redshift 叢集的資料擷取到 Amazon Web Services () 上開發環境中的 Amazon Simple Storage Service (Amazon S3) 儲存貯體AWS。

模式會逐步完成 DEV 和 PROD 帳戶的設定，包括下列項目：
+ 必要的資源
+ AWS Identity and Access Management (IAM) 角色
+ 子網路、安全群組和虛擬私有雲端 (VPC) 的網路調整，以支援 Amazon Redshift 連線
+ 具有 Python 執行時間以測試架構的範例 AWS Lambda 函數

若要授予 Amazon Redshift 叢集的存取權，模式會使用 AWS Secrets Manager 來存放相關登入資料。優點是擁有直接連線至 Amazon Redshift 叢集所需的所有必要資訊，而不需要知道 Amazon Redshift 叢集所在的位置。此外，您可以[監控秘密的使用](https://docs.aws.amazon.com/secretsmanager/latest/userguide/monitoring.html)。

儲存在 Secrets Manager 中的秘密包括 Amazon Redshift 叢集的主機、資料庫名稱、連接埠和相關登入資料。

如需使用此模式時安全性考量的相關資訊，請參閱[最佳實務](#unload-data-from-amazon-redshift-cross-accounts-to-amazon-s3-best-practices)一節。

## 先決條件和限制
<a name="unload-data-from-amazon-redshift-cross-accounts-to-amazon-s3-prereqs"></a>

**先決條件**
+ 在 PROD 帳戶中[執行的 Amazon Redshift 叢集](https://docs.aws.amazon.com/redshift/latest/gsg/new-user.html) 
+ 在 DEV 帳戶中[建立的 S3 儲存貯](https://docs.aws.amazon.com/AmazonS3/latest/userguide/create-bucket-overview.html)體
+ DEV 和 PROD 帳戶之間的 [VPC 對等](https://docs.aws.amazon.com/vpc/latest/peering/create-vpc-peering-connection.html)互連，並相應[地調整路由表](https://docs.aws.amazon.com/vpc/latest/peering/vpc-peering-routing.html) 
+ 同時為對等 VPCs [啟用 DNS 主機名稱和 DNS 解析](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-dns.html) 

**限制**
+ 根據您要查詢的資料量，Lambda 函數可能會逾時。

  如果您的執行需要的時間超過 Lambda 逾時上限 (15 分鐘），請針對 Lambda 程式碼使用非同步方法。此模式的程式碼範例使用適用於 Python 的 [psycopg2](https://github.com/psycopg/psycopg2) 程式庫，目前不支援非同步處理。
+ 有些 AWS 服務 完全無法使用 AWS 區域。如需區域可用性，請參閱[AWS 服務 依區域](https://aws.amazon.com/about-aws/global-infrastructure/regional-product-services/)。如需特定端點，請參閱[服務端點和配額](https://docs.aws.amazon.com/general/latest/gr/aws-service-information.html)頁面，然後選擇服務的連結。

## Architecture
<a name="unload-data-from-amazon-redshift-cross-accounts-to-amazon-s3-architecture"></a>

下圖顯示具有 DEV 和 PROD 帳戶的目標架構。

![DEV 帳戶中的 Lambda VPC 和 PROD 帳戶中的 Amazon Redshift VPC。](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/patterns/images/pattern-img/5c83c617-3a85-4aea-a7a7-930f406d1cef/images/fa4d01df-483d-4454-9711-b391ebbe4629.png)


該圖顯示以下工作流程：

1. DEV 帳戶中的 Lambda 函數會擔任存取 PROD 帳戶中 Secrets Manager 中的 Amazon Redshift 登入資料所需的 IAM 角色。

   Lambda 函數接著會擷取 Amazon Redshift 叢集秘密。

1. DEV 帳戶中的 Lambda 函數會使用資訊，透過對等 VPCs 連線至 PROD 帳戶中的 Amazon Redshift 叢集。

   然後，Lambda 函數會傳送卸載命令來查詢 PROD 帳戶中的 Amazon Redshift 叢集。

1. PROD 帳戶中的 Amazon Redshift 叢集會擔任相關的 IAM 角色，以存取 DEV 帳戶中的 S3 儲存貯體。

   Amazon Redshift 叢集會將查詢的資料卸載至 DEV 帳戶中的 S3 儲存貯體。

**從 Amazon Redshift 查詢資料**

下圖顯示用來擷取 Amazon Redshift 登入資料並連線至 Amazon Redshift 叢集的角色。工作流程是由 Lambda 函數啟動。

![跨帳戶擔任角色的三個步驟程序。](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/patterns/images/pattern-img/5c83c617-3a85-4aea-a7a7-930f406d1cef/images/ab25b72c-773c-4d58-9012-4a3755c181ff.png)


該圖顯示以下工作流程：

1. DEV 帳戶中`CrossAccount-SM-Read-Role`的 會擔任 PROD 帳戶中`SM-Read-Role`的 。

1. `SM-Read-Role` 角色使用附加的政策從 Secrets Manager 擷取秘密。

1. 登入資料用於存取 Amazon Redshift 叢集。

**將資料上傳至 Amazon S3**

下圖顯示擷取資料並將其上傳至 Amazon S3 的跨帳戶讀寫程序。工作流程是由 Lambda 函數啟動。模式[會鏈結 Amazon Redshift 中的 IAM 角色](https://docs.aws.amazon.com/redshift/latest/mgmt/authorizing-redshift-service.html#authorizing-redshift-service-chaining-roles)。來自 Amazon Redshift 叢集的卸載命令會擔任 `CrossAccount-S3-Write-Role`，然後擔任 `S3-Write-Role`。此角色鏈結可讓 Amazon Redshift 存取 Amazon S3。

![取得登入資料、存取 Amazon Redshift 並將資料上傳至 Amazon S3 的角色。](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/patterns/images/pattern-img/5c83c617-3a85-4aea-a7a7-930f406d1cef/images/d2982fc6-1d12-4f9d-9493-a99ce691d693.png)


工作流程包含下列步驟：

1. DEV 帳戶中`CrossAccount-SM-Read-Role`的 會擔任 PROD 帳戶中`SM-Read-Role`的 。

1. 會從 Secrets Manager `SM-Read-Role`擷取 Amazon Redshift 登入資料。

1. Lambda 函數會連線至 Amazon Redshift 叢集並傳送查詢。

1. Amazon Redshift 叢集會擔任 `CrossAccount-S3-Write-Role`。

1. `CrossAccount-S3-Write-Role` 假設 DEV 帳戶中`S3-Write-Role`的 。

1. 查詢結果會卸載至 DEV 帳戶中的 S3 儲存貯體。

## 工具
<a name="unload-data-from-amazon-redshift-cross-accounts-to-amazon-s3-tools"></a>

**AWS 服務**
+ [AWS Key Management Service (AWS KMS)](https://docs.aws.amazon.com/kms/latest/developerguide/overview.html) 可協助您建立和控制密碼編譯金鑰，以協助保護您的資料。
+ [AWS Lambda](https://docs.aws.amazon.com/lambda/latest/dg/welcome.html) 是一項運算服務，可協助您執行程式碼，無需佈建或管理伺服器。它只會在需要時執行程式碼並自動擴展，因此您只需支付使用的運算時間。
+ [Amazon Redshift](https://docs.aws.amazon.com/redshift/latest/gsg/getting-started.html) 是 AWS 雲端中的受管 PB 級資料倉儲服務。
+ [AWS Secrets Manager](https://docs.aws.amazon.com/secretsmanager/latest/userguide/intro.html) 可協助您將程式碼中的硬式編碼憑證 (包括密碼) 取代為 Secrets Manager 的 API 呼叫，以便透過程式設計方法來擷取機密。
+ [Amazon Simple Storage Service (Amazon S3)](https://docs.aws.amazon.com/AmazonS3/latest/userguide/Welcome.html) 是一種雲端型物件儲存服務，可協助您儲存、保護和擷取任何數量的資料。

**程式碼儲存庫**

此模式的程式碼可在 GitHub [unload-redshift-to-s3-python](https://github.com/aws-samples/unload-redshift-to-s3-python/) 儲存庫中使用。

## 最佳實務
<a name="unload-data-from-amazon-redshift-cross-accounts-to-amazon-s3-best-practices"></a>

**安全免責聲明**

實作此解決方案之前，請考慮下列重要的安全建議：
+ 請記住，連接開發和生產帳戶可以增加範圍並降低整體安全狀態。我們建議僅暫時部署此解決方案，擷取所需的資料部分，然後立即銷毀已部署的資源。若要銷毀資源，您應該刪除 Lambda 函數、移除為此解決方案建立的任何 IAM 角色和政策，以及撤銷帳戶之間授予的任何網路存取權。
+ 將任何資料從生產複製到開發環境之前，請先諮詢您的安全與合規團隊。通常不應以此方式複製個人身分識別資訊 (PII)、受保護醫療資訊 (PHI) 和其他機密或管制資料。僅複製公開可用的非機密資訊 （例如，來自商店前端的公有股票資料）。考慮權杖化或匿名化資料，或產生合成測試資料，而不是盡可能使用生產資料。其中一個[AWS 安全原則](https://docs.aws.amazon.com/en_us/wellarchitected/2022-03-31/framework/sec-design.html)是讓人員遠離資料。換句話說，開發人員不應該在生產帳戶中執行操作。
+ 限制對開發帳戶中 Lambda 函數的存取，因為它可以從生產環境中的 Amazon Redshift 叢集讀取資料。
+ 若要避免中斷生產環境，請實作下列建議：
  + 使用單獨的專用開發帳戶進行測試和開發活動。
  + 實作嚴格的網路存取控制，並將帳戶之間的流量限制為僅必要。
  + 監控和稽核對生產環境和資料來源的存取。
  + 為所有涉及的資源和服務實作最低權限的存取控制。
  + 定期檢閱和輪換登入資料，例如 AWS Secrets Manager 秘密和 IAM 角色存取金鑰。
+ 請參閱本文所用服務的下列安全文件：
  + [AWS Lambda 安全性](https://docs.aws.amazon.com/lambda/latest/dg/lambda-security.html)
  + [Amazon Redshift 安全性](https://docs.aws.amazon.com/redshift/latest/mgmt/iam-redshift-user-mgmt.html)
  + [Amazon S3 安全性](https://docs.aws.amazon.com/AmazonS3/latest/userguide/security.html)
  + [AWS Secrets Manager 安全性](https://docs.aws.amazon.com/secretsmanager/latest/userguide/security.html)
  + [IAM 安全最佳實務](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html)

安全性是存取生產資料和資源時的首要考量。一律遵循最佳實務、實作最低權限的存取控制，並定期檢閱和更新您的安全措施。

## 史詩
<a name="unload-data-from-amazon-redshift-cross-accounts-to-amazon-s3-epics"></a>

### 從 Amazon Redshift 查詢資料
<a name="query-data-from-amazon-redshift"></a>


| 任務 | Description | 所需的技能 | 
| --- | --- | --- | 
| 建立 Amazon Redshift 叢集的秘密。 | 若要建立 Amazon Redshift 叢集的秘密，請執行下列動作：[See the AWS documentation website for more details](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/patterns/unload-data-from-amazon-redshift-cross-accounts-to-amazon-s3.html) | DevOps 工程師 | 
| 建立 角色以存取 Secrets Manager。 | 若要建立角色，請執行下列動作：[See the AWS documentation website for more details](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/patterns/unload-data-from-amazon-redshift-cross-accounts-to-amazon-s3.html) | DevOps 工程師 | 

### 將資料上傳至 Amazon S3
<a name="upload-data-to-s3"></a>


| 任務 | Description | 所需的技能 | 
| --- | --- | --- | 
| 建立角色以存取 S3 儲存貯體。 | 若要建立存取 S3 儲存貯體的角色，請執行下列動作：[See the AWS documentation website for more details](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/patterns/unload-data-from-amazon-redshift-cross-accounts-to-amazon-s3.html) | DevOps 工程師 | 
| 建立 Amazon Redshift 角色。 | 若要建立 Amazon Redshift 角色，請執行下列動作：[See the AWS documentation website for more details](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/patterns/unload-data-from-amazon-redshift-cross-accounts-to-amazon-s3.html) | DevOps 工程師 | 

### 部署 Lambda 函數。
<a name="deploy-the-lam-function"></a>


| 任務 | Description | 所需的技能 | 
| --- | --- | --- | 
| 部署 Lambda 函數。 | 若要在對等 VPC 中部署 Lambda 函數，請執行下列動作：[See the AWS documentation website for more details](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/patterns/unload-data-from-amazon-redshift-cross-accounts-to-amazon-s3.html) | DevOps 工程師 | 

### 測試架構
<a name="test-the-architecture"></a>


| 任務 | Description | 所需的技能 | 
| --- | --- | --- | 
| 匯入所需的資源。 | 若要匯入所需的資源，請執行下列命令：<pre>import ast<br />import boto3<br />import psycopg2<br />import base64<br />from botocore.exceptions import ClientError</pre> | 應用程式開發人員 | 
| 執行 Lambda 處理常式函數。 | Lambda 函數使用 AWS Security Token Service (AWS STS) 進行跨帳戶存取和臨時憑證管理。函數使用 AssumeRole API 操作暫時取得 IAM `sm_read_role` 角色的許可。<br />若要執行 Lambda 函數，請使用下列範例程式碼：<pre>def lambda_handler(event, context):<br />    sts_client = boto3.client('sts')<br /><br />    # Secrets Manager Configurations<br />    secret_name = "redshift_creds"<br />    sm_region = "eu-west-1"<br />    sm_read_role = "arn:aws:iam::PROD_ACCOUNT_NUMBER:role/SM-Read-Role"<br /><br />    # S3 Bucket Configurations<br />    s3_bucket_path = "s3://mybucket/"<br />    s3_bucket_region = "eu-west-1"<br />    s3_write_role = "arn:aws:iam::DEV_ACCOUNT_NUMBER:role/S3-Write-Role"<br /><br />    # Redshift Configurations<br />    sql_query = "select * from category"<br />    redshift_db = "dev"<br />    redshift_s3_write_role = "arn:aws:iam::PROD_ACCOUNT_NUMBER:role/CrossAccount-S3-Write-Role"<br /><br />    chained_s3_write_role = "%s,%s" % (redshift_s3_write_role, s3_write_role)<br /><br />    assumed_role_object = sts_client.assume_role(<br />        RoleArn=sm_read_role,<br />        RoleSessionName="CrossAccountRoleAssumption",<br />        ExternalId="YOUR_EXTERNAL_ID",<br />    )<br />    credentials = assumed_role_object['Credentials']<br /><br />    secret_dict = ast.literal_eval(get_secret(credentials, secret_name, sm_region))<br />    execute_query(secret_dict, sql_query, s3_bucket_path, chained_s3_write_role, s3_bucket_region, redshift_db)<br /><br />    return {<br />        'statusCode': 200<br />    }</pre> | 應用程式開發人員 | 
| 取得秘密。 | 若要取得 Amazon Redshift 秘密，請使用下列範例程式碼：<pre>def get_secret(credentials, secret_name, sm_region):<br />    # Create a Secrets Manager client<br />    session = boto3.session.Session()<br />    sm_client = session.client(<br />        service_name='secretsmanager',<br />        aws_access_key_id=credentials['AccessKeyId'],<br />        aws_secret_access_key=credentials['SecretAccessKey'],<br />        aws_session_token=credentials['SessionToken'],<br />        region_name=sm_region<br />    )<br /><br />    try:<br />        get_secret_value_response = sm_client.get_secret_value(<br />            SecretId=secret_name<br />        )<br />    except ClientError as e:<br />        print(e)<br />        raise e<br />    else:<br />        if 'SecretString' in get_secret_value_response:<br />            return get_secret_value_response['SecretString']<br />        else:<br />            return base64.b64decode(get_secret_value_response['SecretBinary'])</pre> | 應用程式開發人員 | 
| 執行卸載命令。 | 若要將資料卸載至 S3 儲存貯體，請使用下列範例程式碼。<pre>def execute_query(secret_dict, sql_query, s3_bucket_path, chained_s3_write_role, s3_bucket_region, redshift_db):<br />    conn_string = "dbname='%s' port='%s' user='%s' password='%s' host='%s'" \<br />                  % (redshift_db,<br />                     secret_dict["port"],<br />                     secret_dict["username"],<br />                     secret_dict["password"],<br />                     secret_dict["host"])<br /><br />    con = psycopg2.connect(conn_string)<br /><br />    unload_command = "UNLOAD ('{}') TO '{}' IAM_ROLE '{}' DELIMITER '|' REGION '{}';" \<br />        .format(sql_query,<br />                s3_bucket_path + str(datetime.datetime.now()) + ".csv",<br />                chained_s3_write_role,<br />                s3_bucket_region)<br /><br />    # Opening a cursor and run query<br />    cur = con.cursor()<br />    cur.execute(unload_command)<br /><br />    print(cur.fetchone())<br />    cur.close()<br />    con.close()</pre> | 應用程式開發人員 | 

### 清除
<a name="clean-up"></a>


| 任務 | Description | 所需的技能 | 
| --- | --- | --- | 
| 刪除 Lambda 函數。 | 為了避免產生意外成本，請移除資源以及 DEV 和 PROD 帳戶之間的連線。<br />若要移除 Lambda 函數，請執行下列動作：[See the AWS documentation website for more details](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/patterns/unload-data-from-amazon-redshift-cross-accounts-to-amazon-s3.html) | DevOps 工程師 | 
| 移除 IAM 角色和政策。 | 從 DEV 和 PROD 帳戶移除 IAM 角色和政策。<br />在 DEV 帳戶中，執行下列動作：[See the AWS documentation website for more details](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/patterns/unload-data-from-amazon-redshift-cross-accounts-to-amazon-s3.html)<br />在 PROD 帳戶中，執行下列動作：[See the AWS documentation website for more details](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/patterns/unload-data-from-amazon-redshift-cross-accounts-to-amazon-s3.html) | DevOps 工程師 | 
| 在 Secrets Manager 中刪除秘密。 | 若要刪除秘密，請執行下列動作：[See the AWS documentation website for more details](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/patterns/unload-data-from-amazon-redshift-cross-accounts-to-amazon-s3.html) | DevOps 工程師 | 
| 移除 VPC 對等互連和安全群組規則。 | 若要移除 VPC 對等互連和安全群組規則，請執行下列動作：[See the AWS documentation website for more details](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/patterns/unload-data-from-amazon-redshift-cross-accounts-to-amazon-s3.html) | DevOps 工程師 | 
| 從 S3 儲存貯體移除資料。 | 若要從 Amazon S3 移除資料，請執行下列動作：[See the AWS documentation website for more details](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/patterns/unload-data-from-amazon-redshift-cross-accounts-to-amazon-s3.html) | DevOps 工程師 | 
| 清除 AWS KMS 金鑰。 | 如果您已為加密建立任何自訂 AWS KMS 金鑰，請執行下列動作：[See the AWS documentation website for more details](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/patterns/unload-data-from-amazon-redshift-cross-accounts-to-amazon-s3.html) | DevOps 工程師 | 
| 檢閱和刪除 Amazon CloudWatch logs。 | 若要刪除 CloudWatch 日誌，請執行下列動作：[See the AWS documentation website for more details](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/patterns/unload-data-from-amazon-redshift-cross-accounts-to-amazon-s3.html) | DevOps 工程師 | 

## 相關資源
<a name="unload-data-from-amazon-redshift-cross-accounts-to-amazon-s3-resources"></a>
+ [Amazon CloudWatch 文件](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/WhatIsCloudWatch.html)
+ [IAM 文件](https://docs.aws.amazon.com/IAM/latest/UserGuide/introduction.html)
+ [Lambda 文件](https://docs.aws.amazon.com/lambda/latest/dg/welcome.html)
+ [Amazon Redshift 文件](https://docs.aws.amazon.com/redshift/latest/gsg/new-user-serverless.html)
+ [Amazon S3 文件](https://docs.aws.amazon.com/AmazonS3/latest/userguide/Welcome.html)
+ [AWS Secrets Manager 文件](https://docs.aws.amazon.com/secretsmanager/latest/userguide/intro.html)
+ [AWS 安全原則](https://docs.aws.amazon.com/en_us/wellarchitected/2022-03-31/framework/sec-design.html)

## 其他資訊
<a name="unload-data-from-amazon-redshift-cross-accounts-to-amazon-s3-additional"></a>

將資料從 Amazon Redshift 卸載至 Amazon S3 之後，您可以使用 Amazon Athena 進行分析。

當您需要存取大量資料時，[Amazon Athena](https://docs.aws.amazon.com/athena/latest/ug/getting-started.html) 是一種大數據查詢服務非常有用。您可以使用 Athena，而無需佈建伺服器或資料庫。Athena 支援複雜的查詢，您可以在不同的物件上執行它。

與大多數一樣 AWS 服務，使用 Athena 的主要好處是它在執行查詢時提供了很大的靈活性，而不會增加複雜性。當您使用 Athena 時，您可以在 Amazon S3 中查詢不同的資料類型，例如 CSV 和 JSON，而無需變更資料類型。您可以從各種來源查詢資料，包括外部 AWS。Athena 可降低複雜性，因為您不必管理伺服器。Athena 會在您執行查詢之前直接從 Amazon S3 讀取資料，而不會載入或變更資料。