為環境設定 Secret Manager

代管 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) 取得這項權限。瞭解如何授予角色

啟用 API

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 密鑰存取者角色就包含這項權限。

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

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

啟用 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:要讀取的 Secret 名稱前置字元,以便取得變數。預設值為 airflow-variables
    • gcp_key_path: Google Cloud 憑證 JSON 檔案的路徑 (如未提供,系統會使用預設服務帳戶)。
    • 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 與 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()

後續步驟