Skip to main content

Command Palette

Search for a command to run...

Eliminating .env Files: A Practical Guide to AWS Secrets Manager for Development Teams

Published
5 min read
M

Cloud DevOps/SRE engineer working with Kubernetes, GitHub Actions, Terraform, and distributed systems. I share practical guides, architecture patterns, and troubleshooting stories learned from running production systems.

Executive Summary

  • Problem: Environment files containing secrets get committed to repositories, shared insecurely, and become stale
  • Solution: Store secrets in AWS Secrets Manager and generate .env files programmatically on demand
  • Result: Zero secrets in git history, auditable access via CloudTrail, and improved developer experience
  • Cost: Approximately $0.40 per secret per month

The Challenge

Credential leaks remain one of the most common security incidents in software development. GitHub's secret scanning detected over 12 million exposed credentials in 2023 alone.

Traditional approaches to managing environment files create multiple failure points:

ApproachFailure Mode
.gitignore rulesNew developers forget to configure, files get committed
SOPS encryptionKey distribution complexity, merge conflicts, learning curve
Shared .env filesSent via Slack, become stale, no access audit
Environment templatesManual copying, outdated examples, human error

Organizations need a solution that eliminates secrets from repositories entirely while maintaining developer productivity.

Technical Architecture

The solution consists of three components: a centralized secret store, a generation script, and CI/CD integration.

Secret Organization

Secrets are organized hierarchically in AWS Secrets Manager:

/application-name/environment/category

For example:

/myapp/dev/database      → DB credentials
/myapp/dev/api-keys      → Third-party API keys
/myapp/prod/database     → Production DB credentials
/myapp/prod/api-keys     → Production API keys

This structure enables granular IAM policies. Developers can access development secrets while production secrets remain restricted to CI/CD pipelines.

Generation Workflow

Developers execute a single command after cloning a repository:

make env

The underlying script:

  1. Validates AWS credentials
  2. Fetches secrets from the appropriate environment path
  3. Generates a .env file locally
  4. Validates the file is gitignored

The generated file never exists in version control. When secrets are updated in AWS Secrets Manager, developers regenerate their local file to receive the latest values.

CI/CD Integration

Pipelines use OIDC authentication to assume AWS roles without stored credentials.

GitHub Actions:

- name: Configure AWS Credentials
  uses: aws-actions/configure-aws-credentials@v4
  with:
    role-to-assume: arn:aws:iam::ACCOUNT:role/github-actions
    aws-region: us-east-1

- name: Generate environment file
  run: python scripts/generate_env.py prod --force

GitLab CI:

script:
  - export $(aws sts assume-role-with-web-identity ...)
  - python scripts/generate_env.py prod --force

Both approaches eliminate stored credentials in CI/CD systems. Access is granted through IAM role assumption with full CloudTrail auditing.

Implementation Guide

Prerequisites

  • AWS account with Secrets Manager access
  • Python 3.8+ with boto3
  • AWS CLI configured for local development

Step 1: Create Secrets

aws secretsmanager create-secret \
  --name /myapp/dev/database \
  --secret-string '{"DB_HOST":"localhost","DB_PASSWORD":"dev123"}'

aws secretsmanager create-secret \
  --name /myapp/dev/api-keys \
  --secret-string '{"STRIPE_KEY":"sk_test_...","API_SECRET":"..."}'

Step 2: Configure IAM Policies

Developer policy (dev environment only):

{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Action": ["secretsmanager:GetSecretValue"],
    "Resource": "arn:aws:secretsmanager:*:*:secret:/myapp/dev/*"
  }]
}

CI/CD policy (production access):

{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Action": ["secretsmanager:GetSecretValue"],
    "Resource": "arn:aws:secretsmanager:*:*:secret:/myapp/prod/*"
  }]
}

Step 3: Deploy the Generation Script

The Python script handles authentication validation, secret fetching, and file generation:

def fetch_all_secrets(environment: str, region: str) -> dict:
    all_secrets = {}
    for key in SECRET_KEYS:
        secret_path = f"/{APP_NAME}/{environment}/{key}"
        secrets = get_secret(secret_path, region)
        all_secrets.update(secrets)
    return all_secrets

Full implementation is available in the linked repository.

Step 4: Configure OIDC for CI/CD

For GitHub Actions:

  1. Create OIDC provider in AWS IAM
  2. Create role with web identity trust policy
  3. Attach secrets access policy
  4. Reference role ARN in workflow

For GitLab CI:

  1. Create OIDC provider for gitlab.com
  2. Create role with appropriate trust policy
  3. Store role ARN in CI/CD variables

Cost Analysis

AWS Secrets Manager pricing is straightforward:

ComponentCost
Secret storage$0.40 per secret per month
API calls$0.05 per 10,000 calls

For a typical team:

Team SizeSecretsMonthly Cost
5 developers20~$8
20 developers50~$20
100 developers100~$40

Compared to dedicated secrets management SaaS solutions ($10+ per user per month), AWS Secrets Manager provides significant cost savings for AWS-native teams.

Security Benefits

AspectBeforeAfter
Secrets in git historyPresentEliminated
Access audit trailNoneCloudTrail
Secret sharingSlack, emailIAM-controlled
Rotation complexityManual everywhereUpdate once, regenerate
RevocationFind all copiesUpdate secret

Measured Outcomes

Six months after implementation:

  • Credential rotation time: Reduced from 2 hours to 5 minutes
  • New developer setup: Reduced from 45 minutes to 10 minutes
  • Security incidents from leaked credentials: Zero
  • Secret sharing via messaging: Eliminated

Recommendations

Use this approach when:

  • Your infrastructure runs on AWS
  • You need auditable access to secrets
  • Developer experience is a priority
  • You want to avoid additional vendor dependencies

Consider alternatives when:

  • You need cross-cloud secret management
  • Your team has no existing AWS footprint
  • You require complex approval workflows for secret access

Conclusion

Eliminating .env files from repositories requires a combination of centralized secret storage, convenient generation tooling, and proper CI/CD integration. AWS Secrets Manager provides a cost-effective solution for teams already operating on AWS infrastructure.

The key insight is that developer experience determines adoption. If generating secrets is harder than committing them, developers will commit them. The make env command must be faster and simpler than any alternative.

Resources


Mateen Ali is a DevOps engineer specializing in cloud infrastructure and security automation. Connect on mateen.tech.