環境に Secret Manager を構成する

Managed Airflow(第 3 世代) | Managed Airflow(第 2 世代) | Managed Airflow(レガシー第 1 世代)

このページでは、Secret Manager を使用して Airflow の接続とシークレットを安全に格納する方法を説明します。

環境に Secret Manager を構成する

このセクションでは、Managed Airflow 環境でシークレットを使用できるように、Secret Manager を構成する方法について説明します。

Secret Manager API を有効にする

コンソール

Secret Manager API を有効にする。

API を有効にするために必要なロール

API を有効にするには、serviceusage.services.enable 権限が必要です。プロジェクトを作成した場合は、オーナーロール(roles/owner)によってこの権限が付与されている可能性があります。それ以外の場合は、Service Usage 管理者ロール(roles/serviceusage.serviceUsageAdmin)によってこの権限を取得できます。ロールを付与する方法をご覧ください

API の有効化

gcloud

Secret Manager API を有効にします。

API を有効にするために必要なロール

API を有効にするには、serviceusage.services.enable 権限が必要です。プロジェクトを作成した場合は、オーナーロール(roles/owner)によってこの権限が付与されている可能性があります。それ以外の場合は、Service Usage 管理者ロール(roles/serviceusage.serviceUsageAdmin)によってこの権限を取得できます。ロールを付与する方法をご覧ください

gcloud services enable secretmanager.googleapis.com

アクセス制御の構成

Airflow が Secret Manager に保存されているシークレットにアクセスできるように、アクセス制御を構成する必要があります。

そのためには、シークレットにアクセスするサービス アカウントに secretmanager.versions.access 権限を持つロールが付与されている必要があります。たとえば、Secret Manager Secret Accessor のロールにはこの権限が含まれています。

このロールは、シークレット レベル、プロジェクト レベル、フォルダレベル、または組織レベルで付与できます。

以下のいずれかの方法を選択します。

Secret Manager バックエンドを有効にして構成する

  1. 次の Airflow 構成オプションをオーバーライドします。

    セクション キー
    secrets backend airflow.providers.google.cloud.secrets.secret_manager.CloudSecretManagerBackend
    airflow.contrib.secrets.gcp_secrets_manager.CloudSecretsManagerBackend
  2. (Airflow 2.10.2 以降) [secrets]backends_order Airflow 構成オプションで、 custom シークレット バックエンドを含むシークレット検索順序が 指定されていることを確認します。このオプションのデフォルト値には、この値がすでに含まれています。

    セクション キー
    secrets backends_order (デフォルト)custom,environment_variable,metastore
  3. 次の Airflow 構成オプションを オーバーライドして、オプションの設定を追加します。

    セクション キー
    secrets backend_kwargs 以下の説明をご覧ください。

    backend_kwargs 値は次の項目を持つ backend_kwargs オブジェクトの JSON 表現です。

    • connections_prefix: 接続を取得するために読み取るシークレット名の接頭辞。デフォルトは airflow-connections です。
    • variables_prefix: 変数を取得するために読み取るシークレット名の接頭辞。デフォルトのは 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 は URL エンコードされている必要があります(パーセントでエンコード)。たとえば、スペース記号を含むパスワードは、次のように URL エンコードする必要があります: postgresql://login:secret%20password@examplehost:9000

Airflow には、接続 URI を生成するための便利なメソッドがあります。JSON エクストラで複雑な URL をエンコードする例については、 Airflow ドキュメントをご覧ください。

Managed Airflow で Secret Manager を使用する

変数と接続を取得するとき、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')

読み取り接続

カスタム演算子を作成する場合を除き、接続に直接アクセスする必要はほとんどありません。ほとんどのフックは、インスタンス化パラメータとして接続名を取得し、タスクの実行時にシークレット バックエンドから接続を自動的に取得する必要があります。

独自のフックを作成する場合には、接続を直接読み取ることが有用な可能性があります。

たとえば、airflow-connections-exampleConnection 接続の場合:

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

BaseHook.get_connectionConnection オブジェクトを返します。接続の URI 文字列表現は、次のように取得できます。

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

次のステップ