Skip to content

Commit 0e8c348

Browse files
authored
feat: add config.INHERIT_ENV to pass local process env vars to all op… (#1677)
1 parent c11fa48 commit 0e8c348

3 files changed

Lines changed: 25 additions & 2 deletions

File tree

docs/inventory-data.rst

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,3 +158,21 @@ External Sources for Data
158158
-------------------------
159159

160160
Because pyinfra is configured in Python, you can pull in data from pretty much anywhere just using other Python packages.
161+
162+
Environment Variables
163+
~~~~~~~~~~~~~~~~~~~~~
164+
165+
``config.INHERIT_ENV`` lets you forward specific environment variables from the machine running pyinfra to all remote operations. This is useful for tools that authenticate via environment variables (SOPS, cloud CLIs, etc.):
166+
167+
.. code:: python
168+
169+
# deploy.py
170+
from pyinfra import config
171+
172+
config.INHERIT_ENV = ["SOPS_AGE_KEY_FILE", "AWS_PROFILE", "GITLAB_TOKEN"]
173+
174+
The priority for environment variables passed to operations is (lowest to highest):
175+
176+
1. ``config.INHERIT_ENV`` — inherited from the caller's ``os.environ``
177+
2. ``config.ENV`` — explicitly set globally in the deploy script
178+
3. ``_env`` per-operation argument — overrides for a single operation

src/pyinfra/api/arguments.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from __future__ import annotations
22

3+
import os
34
from typing import (
45
TYPE_CHECKING,
56
Any,
@@ -85,7 +86,8 @@ class ConnectorArguments(TypedDict, total=False):
8586

8687

8788
def generate_env(config: "Config", value: dict) -> dict:
88-
env = config.ENV.copy()
89+
env = {key: os.environ[key] for key in config.INHERIT_ENV if key in os.environ}
90+
env.update(config.ENV)
8991
env.update(value)
9092
return env
9193

src/pyinfra/api/config.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import importlib.metadata as importlib_metadata # type: ignore[no-redef]
55

66
from os import path
7-
from typing import Iterable, Optional, Set
7+
from typing import Iterable, Optional, Sequence, Set
88

99
from packaging.markers import Marker
1010
from packaging.requirements import Requirement
@@ -63,6 +63,9 @@ class ConfigDefaults:
6363
RETRY: int = 0
6464
# Delay in seconds between retry attempts
6565
RETRY_DELAY: int = 5
66+
# List of environment variable names to inherit from the local process environment.
67+
# These are passed to every shell command, with lower priority than config.ENV.
68+
INHERIT_ENV: Sequence[str] = ()
6669

6770

6871
config_defaults = {key: value for key, value in ConfigDefaults.__dict__.items() if key.isupper()}

0 commit comments

Comments
 (0)