為環境設定 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')

讀取連線

除非您要編寫自訂運算子,否則很少需要直接存取連線。大多數 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()

後續步驟