代管 Airflow (第 3 代) | 代管 Airflow (第 2 代) | 代管 Airflow (舊版第 1 代)
本頁面說明如何使用 Secret Manager 安全地儲存 Airflow 連線和密碼。
事前準備
- 如要使用 Secret Manager,Managed Airflow 環境必須使用 Airflow 1.10.10 以上版本和 Python 3.6 以上版本。
- 不支援 Python 2。
為環境設定 Secret Manager
本節說明如何設定 Secret Manager,以便在 Managed Airflow 環境中使用密鑰。
啟用 Secret Manager API
控制台
啟用 Secret Manager API。
啟用 API 時所需的角色
您必須具備 serviceusage.services.enable 權限,才能啟用 API。如果您建立了專案,可能已透過「擁有者」角色 (roles/owner) 取得這項權限。否則,您可以透過「服務使用情形管理員」角色 (roles/serviceusage.serviceUsageAdmin) 取得這項權限。瞭解如何授予角色。
gcloud
啟用 Secret Manager API:
啟用 API 時所需的角色
您必須具備 serviceusage.services.enable 權限,才能啟用 API。如果您建立了專案,可能已透過「擁有者」角色 (roles/owner) 取得這項權限。否則,您可以透過「服務使用情形管理員」角色 (roles/serviceusage.serviceUsageAdmin) 取得這項權限。瞭解如何授予角色。
gcloud services enable secretmanager.googleapis.com
設定存取控管機制
您必須設定存取控管,Airflow 才能存取儲存在 Secret Manager 中的密鑰。
如要這麼做,存取密鑰的服務帳戶必須具備含有 secretmanager.versions.access 權限的角色。舉例來說,Secret Manager 密鑰存取者角色就包含這項權限。
您可以在祕密、專案、資料夾或機構層級授予這個角色。
請使用下列其中一種方式:
覆寫 Airflow 存取 Secret Manager 時使用的服務帳戶。
- 將這個角色授予服務帳戶。
- 將
backend_kwargsAirflow 設定選項的gcp_key_path參數設為指向含有服務帳戶憑證的 JSON 檔案。
啟用 DAG 序列化
一般來說,您應該只在運算子的 execute() 方法中,或使用 Jinja 範本,使用 Secret Manager 後端。舉例來說,您可以使用 var.value.example_var 擷取變數。
Airflow 網路伺服器是透過權限受限的其他服務帳戶執行,因此無法存取 Secret Manager 中的密鑰。如果 DAG 程式碼在 DAG 處理期間存取密鑰 (不只是從工作),且無法調整為從 execute() 方法內存取密鑰,請啟用 DAG 序列化。完成這項操作後,Airflow 網路伺服器會採用已處理的 DAG,不需要存取密鑰。
啟用及設定 Secret Manager 後端
覆寫下列 Airflow 設定選項:
區段 鍵 值 secretsbackendairflow.providers.google.cloud.secrets.secret_manager.CloudSecretManagerBackend如要新增選用設定,請覆寫下列 Airflow 設定選項:
區段 鍵 值 secretsbackend_kwargs請參閱下文說明。 backend_kwargs值是backend_kwargs物件的 JSON 表示法,包含下列欄位:connections_prefix:要讀取的密碼名稱前置字元,以便取得連線。預設值為airflow-connections。variables_prefix:要讀取的 Secret 名稱前置字元,以便取得變數。預設值為airflow-variables。gcp_key_path: Google Cloud 憑證 JSON 檔案的路徑 (如未提供,系統會使用預設服務帳戶)。gcp_keyfile_dict: Google Cloud 憑證 JSON 字典。與gcp_key_path互斥。sep:用於串連connections_prefix和conn_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 與 Managed Airflow
擷取變數和連線時,Managed Airflow 會先檢查 Secret Manager。如果找不到要求的變數或連線,Managed Airflow 會檢查環境變數和 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')
可讀取連線
除非您要編寫自訂運算子,否則很少需要直接存取連線。大多數 Hook 會將連線名稱做為其實例化參數,並在執行工作時自動從密碼後端擷取連線。
撰寫自己的 Hook 時,直接讀取連線可能很有用。
舉例來說,如果是 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()