Learning Platform
Глоссарий Troubleshooting
Урок 11.06 · 26 мин
Продвинутый
AWS Secrets ManagerGCP Secret ManagerAzure Key VaultIAMMulti-Cloud

Secrets Backends — облачные провайдеры

В прошлом уроке мы разобрали HashiCorp Vault как self-hosted secret store. Этот урок — про managed alternatives от облаков: AWS Secrets Manager, GCP Secret Manager, Azure Key Vault. У каждого свой trade-off по cost / features / integration с native IAM.


AWS Secrets Manager

Provider package:

pip install apache-airflow-providers-amazon

Конфигурация в airflow.cfg:

[secrets]
backend = airflow.providers.amazon.aws.secrets.secrets_manager.SecretsManagerBackend
backend_kwargs = {
  "connections_prefix": "airflow/connections",
  "variables_prefix": "airflow/variables",
  "config_prefix": "airflow/config",
  "region_name": "eu-west-1",
  "profile_name": null
}

Pathing convention — точка / в имени secret (AWS Secrets Manager поддерживает hierarchy через /):

airflow/connections/pg_prod_warehouse
airflow/connections/snowflake_prod
airflow/variables/api_endpoint

Secret value — JSON для Connection, plain string для Variable:

# AWS CLI: create connection secret
aws secretsmanager create-secret \
  --name airflow/connections/pg_prod_warehouse \
  --secret-string '{
    "conn_type": "postgres",
    "login": "airflow",
    "password": "secretPwd",
    "host": "db.internal",
    "port": 5432,
    "schema": "warehouse",
    "extra": "{\"sslmode\":\"require\"}"
  }'

# Variable secret (plain string)
aws secretsmanager create-secret \
  --name airflow/variables/api_endpoint \
  --secret-string "https://api.example.com/v2"

Authentication

SecretsManagerBackend использует boto3 default credential chain. Это даёт несколько options:

AWS auth flow в Airflow
boto3 client initПри первом запросе backend instantiates boto3.client('secretsmanager'). boto3 проходит standard credential chain — без явных credentials в backend_kwargs.
Priority 1: profile_nameЕсли в backend_kwargs указан profile_name='production' — boto3 использует [production] section из ~/.aws/credentials. Обычно для local dev — в production не используйте.
Priority 2: ENVAWS_ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEY. Anti-pattern для production — это long-lived credentials в env. OK для local dev / one-off scripts.
Priority 3: EC2 instance profileЕсли Airflow на EC2 — IAM Role attached к EC2 даёт credentials через IMDS (Instance Metadata Service). boto3 автоматически использует. Это secure pattern для EC2 deployments.
Priority 4: IRSA (k8s)IAM Roles for Service Accounts. Airflow pod имеет ServiceAccount с annotation eks.amazonaws.com/role-arn. AWS Pod Identity Webhook inject-ит ENV vars (AWS_WEB_IDENTITY_TOKEN_FILE + AWS_ROLE_ARN). boto3 detects и использует. Gold standard для EKS deployments.
API call: GetSecretValueSecretsManager:GetSecretValue с secret name. Возвращает SecretString (JSON для Connection, plain для Variable). Backend парсит и возвращает Airflow Connection object.

Best practice для EKS — IRSA:

# k8s Service Account для Airflow
apiVersion: v1
kind: ServiceAccount
metadata:
  name: airflow
  namespace: airflow
  annotations:
    eks.amazonaws.com/role-arn: arn:aws:iam::123456789:role/airflow-secrets-reader

IAM Role airflow-secrets-reader:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "secretsmanager:GetSecretValue",
        "secretsmanager:DescribeSecret"
      ],
      "Resource": "arn:aws:secretsmanager:eu-west-1:123456789:secret:airflow/*"
    }
  ]
}

ResourceARN с airflow/* ограничивает IAM Role только Airflow secrets — нельзя случайно прочитать app secrets других teams.

AWS Secrets Manager pricing

  • $0.40 per secret per month
  • $0.05 per 10k API calls

Для типичного deployment с 50 secrets:

  • Storage: 50 × 0.40=0.40 = **20/month**
  • API calls (с use_cache=True, ttl=900): 50 secrets × 4 reads/hour × 720h × N pods. Для 20 pods это ~3M calls/month = $15
  • Total: $35/month — обычно negligible vs total infra cost

Без caching API calls могут пробить $100+/month easily.

Automatic rotation

AWS Secrets Manager имеет builtin automatic rotation через Lambda:

aws secretsmanager rotate-secret \
  --secret-id airflow/connections/pg_prod_warehouse \
  --rotation-lambda-arn arn:aws:lambda:eu-west-1:123:function:rotate-pg-password \
  --rotation-rules AutomaticallyAfterDays=30

Lambda function отвечает за фактическое generate нового password + update Postgres. Это comparable с Vault dynamic secrets, но через managed Lambda → меньше operations overhead.

Airflow получит rotated secret автоматически на следующий cache miss (или process restart).


GCP Secret Manager

Provider:

pip install apache-airflow-providers-google

Config:

[secrets]
backend = airflow.providers.google.cloud.secrets.secret_manager.CloudSecretManagerBackend
backend_kwargs = {
  "connections_prefix": "airflow-connections",
  "variables_prefix": "airflow-variables",
  "config_prefix": "airflow-config",
  "gcp_key_path": null,
  "project_id": "my-gcp-project",
  "sep": "-"
}

Pathing — GCP Secret Manager не имеет hierarchy через /, секреты flat. Backend использует sep='-':

airflow-connections-pg_prod_warehouse
airflow-connections-snowflake_prod
airflow-variables-api_endpoint

Note underscore vs dash: GCP Secret names regex [a-zA-Z0-9_-]{1,255} — underscores допустимы.

gcloud secrets create airflow-connections-pg_prod_warehouse \
  --data-file=- <<EOF
{
  "conn_type": "postgres",
  "login": "airflow",
  "password": "secretPwd",
  "host": "db.internal",
  "port": 5432,
  "schema": "warehouse"
}
EOF

gcloud secrets create airflow-variables-api_endpoint \
  --data-file=- <<EOF
https://api.example.com/v2
EOF

Auth — Workload Identity (GKE gold standard)

В GKE предпочтительный pattern — Workload Identity:

# k8s SA
apiVersion: v1
kind: ServiceAccount
metadata:
  name: airflow
  namespace: airflow
  annotations:
    iam.gke.io/gcp-service-account: [email protected]

GCP Service Account airflow-secrets@:

gcloud projects add-iam-policy-binding my-gcp-project \
  --member="serviceAccount:[email protected]" \
  --role="roles/secretmanager.secretAccessor"

Внутри pod GCP client libraries detect Workload Identity и автоматически получают access tokens.

GCP Secret Manager pricing

  • $0.06 per active secret per month
  • $0.03 per 10k operations

50 secrets:

  • Storage: 50 × 0.06=0.06 = **3/month**
  • Operations: ~3M/month = $9
  • Total: $12/month — cheapest из трёх cloud providers

GCP заметно cheaper than AWS Secrets Manager в storage (6.6× difference на secret).

Versioning

GCP Secret Manager имеет immutable versions. Каждый gcloud secrets versions add создаёт новую version, старые сохраняются. По default backend читает latest, но можно reference конкретную version:

backend_kwargs = {
  "connections_prefix": "airflow-connections",
  "version": "5"  # читать конкретную версию
}

Используется редко — обычно latest. Versioning полезен для rollback при инциденте.


Azure Key Vault

Provider:

pip install apache-airflow-providers-microsoft-azure

Config:

[secrets]
backend = airflow.providers.microsoft.azure.secrets.key_vault.AzureKeyVaultBackend
backend_kwargs = {
  "connections_prefix": "airflow-connections",
  "variables_prefix": "airflow-variables",
  "config_prefix": "airflow-config",
  "vault_url": "https://my-airflow-kv.vault.azure.net",
  "sep": "-"
}

Azure Key Vault имеет ограничения на secret name: [0-9a-zA-Z-]{1,127}. Underscores и слэши НЕ работают! Это создаёт проблему — airflow-connections/pg_prod_warehouse невалидно. Поэтому sep='-' обязателен (вместо /), и conn_id не должен содержать underscores (или они трансформируются).

В реальности конвертация: conn_id pg_prod_warehouse → Key Vault secret name airflow-connections-pg-prod-warehouse (Airflow меняет _-). Это must know при настройке.

az keyvault secret set \
  --vault-name my-airflow-kv \
  --name airflow-connections-pg-prod-warehouse \
  --value '{"conn_type":"postgres","login":"airflow","password":"secretPwd","host":"db.internal","port":5432,"schema":"warehouse"}'

Auth — Managed Identity (AKS gold standard)

Azure Key Vault интегрируется с Azure AD Managed Identity. AKS pods могут иметь User-Assigned Managed Identity:

apiVersion: v1
kind: ServiceAccount
metadata:
  name: airflow
  namespace: airflow
  annotations:
    azure.workload.identity/client-id: <managed-identity-client-id>

Grant Managed Identity роль:

az role assignment create \
  --role "Key Vault Secrets User" \
  --assignee <managed-identity-client-id> \
  --scope /subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.KeyVault/vaults/my-airflow-kv

В Airflow используется DefaultAzureCredential из azure-identity (auto-detect chain), которая поддерживает Workload Identity, Managed Identity, SP credentials, az CLI.

Pricing

  • $0.03 per 10k operations (read-heavy operations)
  • No charge per secret stored (within limit)
  • HSM-backed secrets — significantly more expensive ($1+ per key)

For 50 secrets:

  • Storage: $0 (under quota)
  • Operations: ~3M/month = $9
  • Total: $9/month — самый дешёвый из трёх

Сравнение

AWS vs GCP vs Azure Secret Stores
AWS Secrets Manager$0.40/secret + $0.05/10k ops. Native rotation через Lambda — builtin. IRSA для EKS — solid. Best для AWS-heavy stacks. 100k+ orgs. Может быть expensive для many small secrets.
Azure Key Vault$0/secret под quota + $0.03/10k ops. Managed Identity для AKS — solid. Самый cheap. Naming restriction (no underscores) — pitfall. HSM-backed option для compliance.
Best for AWS-stackЕсли у вас AWS workloads, IRSA, RDS, S3 — оставайтесь в AWS Secrets Manager. Tight integration, builtin rotation, audit через CloudTrail. Trade-off: дороже но less moving parts.
Best for GCP-stackGCP workloads → GCP Secret Manager. Cheaper, Workload Identity лучше IAM model в k8s, versioning встроен. Rotation Cloud Functions требует extra setup.
Best for hybrid / on-premHashiCorp Vault (см. урок 05). Self-hosted, multi-cloud agnostic, dynamic secrets, advanced policies. Trade-off: operational burden — нужно поддерживать Vault cluster sami.

Multi-cloud strategy

Realistic enterprise scenario — Airflow на AWS читает secrets из GCP project (потому что GCP ML team owns dataset). Two options:

Option 1: Multiple Backends в chain

[secrets]
backend = airflow.providers.amazon.aws.secrets.secrets_manager.SecretsManagerBackend,airflow.providers.google.cloud.secrets.secret_manager.CloudSecretManagerBackend
backend_kwargs = '{"aws":{...}, "gcp":{...}}'

Airflow попробует AWS first, потом GCP. Trade-off: каждый lookup делает 2 round-trips для secrets, которых не существует в AWS.

Option 2: Vault как unified gateway

Vault sets up secret engines для AWS Secrets Manager и GCP Secret Manager, Airflow читает только из Vault. Vault internally proxies к cloud. Trade-off: + Vault complexity, но единая audit + RBAC.

Option 3: Replication

Workflow в external system периодически копирует secrets из source provider в target. Airflow читает только из one provider. Trade-off: stale data до next sync run.

Production reality — обычно option 2 (Vault) для enterprise или option 1 (chain) для simple cases.


Common pitfalls — все три провайдера

  1. Region mismatch: Airflow в eu-west-1, secrets в us-east-1. AWS возвращает ResourceNotFoundException. Always set region_name explicitly.
  2. Prefix typo: airflow/connections/ vs airflow-connections/ — путь не совпадает, lookup возвращает None silently, потом fallback на DB → unexpected credentials.
  3. JSON malformed: extra field как nested JSON string (escaped quotes!) — должно быть валидным JSON для extra_dejson.
  4. IAM/RBAC underspec: missing secretsmanager:DescribeSecret (AWS требует для GetSecretValue без VersionId) — backend получит AccessDenied.
  5. Naming restrictions: Azure не любит _. AWS — / OK. GCP — flat без /. Тестируйте на edge case naming перед production deploy.

When to choose what

HashiCorp Vault: multi-cloud / on-prem / dynamic secrets / fine-grained policies / when compliance требует self-hosted.

AWS Secrets Manager: AWS-only workload, builtin RDS rotation важна, есть AWS Premium Support contract.

GCP Secret Manager: GCP-only workload, нужен cheap-est storage, comfortable с lighter rotation tooling.

Azure Key Vault: Azure-only workload, нужен HSM-backed secrets для compliance, OK с naming restrictions.

None (DB-only): dev / local environments, < 10 secrets, no audit requirements. Никогда production.


Проверка знанийKnowledge check
Airflow на EKS, IRSA configured, читает 30 secrets из AWS Secrets Manager. После migration с DB на Secrets Manager scheduler начал занимать 3-5 минут на parse cycle (раньше — 15 секунд). API rate: 1k RPS на Secrets Manager. AWS support звонит про rate limit. Что происходит и fix?
ОтветAnswer
Root cause — top-level Variable.get / Hook.get_connection в DAG-файлах. DAG Processor парсит каждые 30s (default min_file_process_interval). Если в top-level есть Connection lookups, каждый parse cycle делает API calls. 50 DAGs × 5 connection lookups × parsing_processes=4 = 1000 API calls per parse cycle. AWS Secrets Manager default rate limit GetSecretValue = 5000 RPS per region (per account), но throttling может начаться раньше под burst load. С migration в DB SQL queries были fast (~ms locally), AWS Secrets Manager — HTTP API на расстоянии 5-20ms каждый. Slow parse + throttling = cascading 3-5 min parse times. Fix: (1) **Enable backend caching**: [secrets] use_cache = True, cache_ttl_seconds = 600. Это снизит rate в 30-60×. Critical for production. (2) **Find top-level Variable.get / Hook.get_connection**: grep dags/ -r 'Variable.get\|BaseHook.get_connection' — каждое такое использование вне @task должно быть переписано. (3) **connections_lookup_pattern**: ограничить какие conn_id вообще идут в Secrets Manager. Например, '^prod_.*' — staging/dev connections напрямую в DB. (4) **Бесполезные lookups**: убедитесь, что DAGs не пытаются prefetch credentials которые не используются (например, factory которая создаёт DAGs для всех ENVs но deployed только prod). (5) Long-term: рассмотрите Vault как secret gateway если multi-cloud / нужны dynamic secrets / better caching (Vault Performance Replicas read-scale).Лесон: миграция metadata DB → API-backed secrets requires audit DAG codebase first для anti-patterns.

Проверьте понимание

Результат: 0 из 0
Прикладной
Вопрос 1 из 4. AWS SecretsManagerBackend на EKS — production auth pattern?

Закончили урок?

Отметьте его как пройденный, чтобы отслеживать свой прогресс

Войдите чтобы оценить урок

Прогресс модуля
0 из 7