為環境設定 Secret Manager

Cloud Composer 3 | Cloud Composer 2 | Cloud Composer 1

本頁面說明如何使用 Secret Manager 安全地儲存 Airflow 連線和密鑰。

事前準備

  • 如要使用 Secret Manager,Cloud Composer 環境必須使用 Airflow 1.10.10 以上版本和 Python 3.6 以上版本。
  • 不支援 Python 2。

為環境設定 Secret Manager

本節說明如何設定 Secret Manager,以便在 Cloud Composer 環境中使用機密資料。

啟用 Secret Manager API

主控台

Enable the Secret Manager API.

Enable the API

gcloud

Enable the Secret Manager API:

gcloud services enable secretmanager.googleapis.com

設定存取控管機制

您必須設定存取權控管,讓 Airflow 能夠存取儲存在 Secret Manager 中的密鑰。

為此,存取機密資料的服務帳戶必須具備具有 secretmanager.versions.access 權限的角色。舉例來說,Secret Manager 密鑰存取者角色就包含這項權限。

您可以在機密資料、專案、資料夾或機構層級授予這個角色。

請使用下列其中一種方式:

啟用 DAG 序列化

一般來說,您應該只在運算子的 execute() 方法中,或搭配 Jinja 範本使用 Secret Manager 後端。例如,您可以使用 var.value.example_var 擷取變數。

Airflow 網路伺服器是透過權限受限的不同服務帳戶執行,因此無法存取 Secret Manager 中的密鑰。如果 DAG 程式碼在 DAG 處理期間 (而非僅在工作中) 存取機密資料,且無法調整為從 execute() 方法中存取機密資料,請啟用 DAG 序列化。完成後,Airflow 網路伺服器會採用已處理的 DAG,且不需要存取機密資料。

啟用及設定 Secret Manager 後端

  1. 覆寫下列 Airflow 設定選項:

    區段
    secrets backend airflow.providers.google.cloud.secrets.secret_manager.CloudSecretManagerBackend
  2. 覆寫下列 Airflow 設定選項,即可新增選用設定:

    區段
    secrets backend_kwargs 請參閱以下說明。

    backend_kwargs 值是 backend_kwargs 物件的 JSON 表示法,其中包含下列欄位:

    • connections_prefix:要讀取的密鑰名稱前置字串,以便取得連線。預設值為 airflow-connections
    • variables_prefix:要讀取的秘密名稱前置字串,以便取得變數。預設值為 airflow-variables
    • gcp_key_path:憑證 JSON 檔案的路徑 (如果未提供,系統會使用預設服務帳戶)。 Google Cloud
    • gcp_keyfile_dict: Google Cloud 憑證 JSON 字典。與 gcp_key_path 互斥。
    • sep:用於串連 connections_prefixconn_id 的分隔符。預設值為 -
    • project_id: Google Cloud 密鑰儲存的專案 ID。

    例如,backend_kwargs 的值可以是:{"project_id": "<project id>", "connections_prefix":"example-connections", "variables_prefix":"example-variables", "sep":"-"}

在 Secret Manager 中新增連結和變數

按照「建立密鑰和版本」一文中的步驟建立密鑰。

變數

  • 必須使用 [variables_prefix][sep][variable_name] 格式。
  • [variables_prefix] 的預設值為 airflow-variables
  • 預設分隔符號 [sep]-

舉例來說,如果變數名稱是 example-var,則機密名稱就是 airflow-variables-example-var

連線名稱

  • 必須使用 [connection_prefix][sep][connection_name] 格式。
  • [connection_prefix] 的預設值為 airflow-connections
  • 預設分隔符號 [sep]-

舉例來說,如果連線名稱是 exampleConnection,則機密名稱就是 airflow-connections-exampleConnection

連線值

  • 必須使用 URI 表示法。例如:postgresql://login:secret@examplehost:9000

  • URI 必須是網址編碼 (百分比編碼)。舉例來說,含有空格符號的密碼必須以網址編碼方式編碼,如下所示:postgresql://login:secret%20password@examplehost:9000

Airflow 提供便利方法,可產生連線 URI。如要瞭解如何使用 JSON 額外資料編碼複雜的網址,請參閱 Airflow 說明文件

搭配使用 Secret Manager 和 Cloud Composer

擷取變數和連線時,Cloud Composer 會先檢查 Secret Manager。如果找不到要求的變數或連線,Cloud Composer 會檢查環境變數和 Airflow 資料庫。

使用 Jinja 範本讀取變數

您可以使用 Secret Manager 讀取使用 Jinja 範本的變數,以便針對範本運算子欄位 (在執行時解析) 進行解析。

針對 airflow-variables-secret_filename 密鑰:

file_name = '{{var.value.secret_filename}}'

使用自訂運算子和回呼讀取變數

您也可以使用 Secret Manager 讀取自訂運算子中的變數,或從運算子讀取回呼方法。從 DAG 內部讀取變數可能會對效能造成負面影響,因此如果要在 DAG 中使用變數,請使用 Jinja 範本。

例如,針對 airflow-variables-secret_filename 機密金鑰:

from airflow.models.variable import Variable
file_name = Variable.get('secret_filename')

讀取連線

除非您要編寫自訂運算子,否則不太需要直接存取連線。大多數鉤子會將連線名稱做為其例項化參數,並應在執行工作時自動從機密後端擷取連線。

在編寫自己的掛鉤時,直接讀取連線可能會很實用。

例如,針對 airflow-connections-exampleConnection 連線:

from airflow.hooks.base_hook import BaseHook
exampleConnection = BaseHook.get_connection('exampleConnection')

BaseHook.get_connection 會傳回 Connection 物件。您可以取得連線的 URI 字串表示法,如下所示:

exampleConnectionUri = BaseHook.get_connection('exampleConnection').get_uri()

後續步驟