Environment variables are key-value pairs in a process's execution environment. Applications read them through language APIs, such as os.environ["TABLE_NAME"] in Python or process.env.TABLE_NAME in Node.js. Typical settings include database endpoints, queue URLs, resource names, and logging levels. Values are strings, so applications must explicitly parse numbers, validate allowed values, and distinguish missing values from empty strings. A value of "false" is not automatically a Boolean false.
In cloud deployments, environment variables help separate the application artifact from its deployment configuration. A build pipeline can produce one ZIP archive or container image, then deploy that same artifact to development, staging, and production with different configuration values. For example, TABLE_NAME might identify a development database table in one environment and a production table in another. The variable identifies the resource; it does not grant permission to access it. The application's workload identity still needs the appropriate authorization.
Preparing an artifact requires distinguishing configuration from dependencies. Environment variables cannot install a missing library, provide a native binary, or replace an incompatible runtime. Libraries must still be packaged with the application, supplied through an appropriate layer, or included in the container image. Configuration files remain useful for structured settings, while environment variables provide simple deployment-specific values or paths to those files. A local .env file is only a file until a development tool or library loads its contents; cloud runtimes do not universally load it automatically.
For AWS Lambda, user-defined environment variables are function configuration rather than files that must be added to the deployment ZIP. A function can read BUCKET_NAME to select an S3 bucket while using its execution role for access. Lambda environment variables are encrypted at rest, have a combined size limit of 4 KB, and are stored as literal strings without shell-style expansion. Setting one variable to a string containing another variable's name does not cause Lambda to substitute its value.
Lambda configuration has important lifecycle rules. Environment variables become part of a published function version's immutable configuration; changes are made to the unpublished version and require publishing a new version for a versioned rollout. Updating the environment variable map through the Lambda configuration API replaces the entire map, so deployment tooling must preserve entries that should remain. Reserved variable names cannot be overridden. Memory, timeout, concurrency, runtime, handler, layers, extensions, triggers, and destinations are separate configuration concerns, not settings changed simply by inventing similarly named application environment variables.
Environment variables are usually startup configuration, not a live configuration distribution system. Changing a container task definition does not rewrite the environment of already running containers; replacement tasks must start with the new settings. Likewise, changing a secret in a central store does not automatically refresh a value previously injected into a process. For settings that must change without restarting workloads, use explicit runtime retrieval or a configuration client with a defined refresh and caching policy.
Security is a major trade-off. Environment variables are convenient but may be exposed through diagnostic output, deployment tooling, or inspection by users with sufficient permissions. Encryption at rest does not prevent application code from reading plaintext values during execution. Prefer a secrets manager for credentials and sensitive tokens, use workload roles instead of static cloud access keys, and avoid logging the complete process environment. Where a platform injects secrets into environment variables, account for both exposure and restart requirements after rotation.
Reliable deployments treat configuration as a contract. Document required names, validate values during startup, and fail with a useful error when critical settings are absent. Define precedence when command-line arguments, files, and environment variables overlap. Manage nonsecret configuration through reviewed deployment definitions, and test configuration alongside the artifact so that a correct build does not fail because of a missing or malformed setting.