Configure Secret Manager for your environment

Cloud Composer 1 | Cloud Composer 2

This page shows how to use Secret Manager to securely store Airflow connections and secrets.

Before you begin

  • To use Secret Manager, your Cloud Composer environment must use Airflow 1.10.10 or later and Python 3.6 or later.
  • Python 2 is not supported.

Configure Secret Manager for your environment

This section explains how to configure Secret Manager so that you can use secrets with your Cloud Composer environment.

Enable the Secret Manager API

Console

Enable the Secret Manager API.

Enable the API

gcloud

Enable the Secret Manager API:

gcloud services enable secretmanager.googleapis.com

Configure access control

You must configure access control so that Airflow can access secrets stored in Secret Manager.

To do so, the service account that accesses secrets must have a role with the secretmanager.versions.access permission. For example, the Secret Manager Secret Accessor role includes this permission.

You can grant this role at the Secret, Project, Folder, or Org level.

Use one of the following options:

Enable DAG serialization

In general, you should only use the Secret Manager backend from within the execute() methods of your operators, or with the Jinja templates. For example, you can retrieve variables using var.value.example_var.

The Airflow web server runs under a different service account with limited permissions, so it cannot access secrets in Secret Manager. If your DAG code accesses secrets during DAG processing (not just from tasks) and it is not possible to adjust it to access secrets from within the execute() methods, then enable DAG serialization. After you do so, the Airflow web server takes processed DAGs and does not need access to secrets.

Enable and configure the Secret Manager backend

  1. Override the following Airflow configuration option:

    Section Key Value
    secrets backend airflow.providers.google.cloud.secrets.secret_manager.CloudSecretManagerBackend
  2. Add optional settings by overriding the following Airflow configuration option:

    Section Key Value
    secrets backend_kwargs See the following description.

    The backend_kwargs value is the JSON representation of the backend_kwargs object with the following fields:

    • connections_prefix: Specifies the prefix of the secret name to read in order to get Connections. Default is: airflow-connections.
    • variables_prefix: Specifies the prefix of the secret name to read in order to get Variables. Default is: airflow-variables.
    • gcp_key_path: Path to the Google Cloud Credential JSON file (if not provided, the default service account is used).
    • gcp_keyfile_dict: The Google Cloud Credential JSON dictionary. Mutually exclusive with gcp_key_path.
    • sep: separator used to concatenate connections_prefix and conn_id. Default: -.
    • project_id: The Google Cloud Project Id where secrets are stored.

    For example, the value of backend_kwargs can be: {"project_id": "<project id>", "connections_prefix":"example-connections", "variables_prefix":"example-variables", "sep":"-"}.

Add connections and variables in Secret Manager

Create secrets by following steps outlined in Creating secrets and versions.

Variables

  • Must use the [variable_prefix][sep][variable_name] format.
  • The default value for [variable_prefix] is airflow-variables.
  • The default separator [sep] is -.

For example, if the variable name is example-var, then the secret name is airflow-variables-example-var.

Connection names

  • Must use the [connection_prefix][sep][connection_name] format.
  • The default value for [connection_prefix] is airflow-connections.
  • The default separator [sep] is -.

For example, if the connection name is exampleConnection, then the secret name is airflow-connections-exampleConnection.

Connection values

  • Must use URI representation. For example, mysql://login:password@examplehost:9000.

  • The URI must be URL-encoded (percent encoded). For example, a password that has a space symbol in it must be URL-encoded as follows: mysql://login:secret%20password@examplehost:9000.

Airflow has a convenience method for generating connection URIs. An example of how to encode a complex URL with JSON extras is available in the Airflow documentation.

Use Secret Manager with Cloud Composer

When fetching variables and connections, Cloud Composer checks Secret Manager first. If the requested variable or connection is not found, Cloud Composer then checks the environment variables and the Airflow database.

Read variables using Jinja templating

You can use Secret Manager to read variables with Jinja templating for templated operator fields (resolved at the execution time).

For the airflow-variables-secret_filename secret:

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

Read variables using custom operators and callbacks

You can also use Secret Manager to read variables in custom operators or callback methods from operators. Reading variables from inside DAGs can negatively impact performance, so use Jinja templates if you want to use variables in your DAGs.

For example, for the airflow-variables-secret_filename secret:

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

Read connections

Unless you are writing a custom operator, you should rarely need to access connections directly. Most hooks get the connection name as their instantiation parameter, and should retrieve connections from the secret backend automatically when tasks are executed.

Reading connections directly may be useful when writing your own hook.

For example, for the airflow-connections-exampleConnection connection:

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

BaseHook.get_connection returns a Connection object. It is possible to get the URI string representation of a connection like this:

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

What's next