Development Environments
Adjust Technical Level
Select your expertise level to customize content
Development environments represent the different stages software passes through in its lifecycle, from initial coding to production deployment. Each environment has distinct purposes, configurations, and access controls designed to ensure quality and stability at each phase of development.
Understanding Environment Types
Technical Perspective
Think of software environments like the journey of a new car from design to the showroom:
- Development Environment: The design studio and workshop where engineers build and test individual car parts. Things can break here without affecting customers.
- Integration Environment: The assembly line where all the parts come together for the first time to make sure they fit and work together.
- Testing Environment: The test track where professional testers put the assembled car through rigorous tests under different conditions.
- Staging Environment: The final inspection area where the car is checked exactly as it would be delivered to customers, possibly with select customers invited for a test drive.
- Production Environment: The showroom and roads where real customers use the car in real-world conditions.
Each stage adds more scrutiny and gets closer to real-world conditions, reducing the risk of problems when real customers are involved.
Non-Technical Perspective
Software development environments form a promotion pathway for code, with each environment serving specific purposes:
- Development Environment (Dev): Individual developer workstations or shared development servers where initial code is written and tested. Typically runs with debugging enabled, verbose logging, and developer-friendly configurations.
- Integration Environment: Where code from multiple developers is merged and tested together to ensure components work properly as a unified system.
- Testing/QA Environment: Dedicated to systematic testing by QA teams. Contains test data and configurations optimized for various testing types (functional, performance, security).
- Staging/Pre-production Environment: Nearly identical to production, used for final validation before deployment. Often used for user acceptance testing (UAT).
- Production Environment (Prod): Live environment serving real users with actual data. Optimized for performance, security, and stability rather than debugging or testing.
Each environment is governed by specific access controls, configuration management, and deployment processes to maintain its integrity.
Environment Characteristics Comparison
Characteristic | Development | Integration | Testing/QA | Staging | Production |
---|---|---|---|---|---|
Primary Users | Developers | Build Systems, Developers | QA Engineers, Testers | Business Stakeholders, UAT Testers | End Users, Customers |
Data | Synthetic, Minimal | Test Datasets | Comprehensive Test Data | Anonymized Production Data | Real Customer Data |
Change Frequency | Very Frequent (minutes/hours) | Frequent (hours/days) | Scheduled (days) | Controlled (days/weeks) | Planned Releases (weeks/months) |
Performance | Not Optimized | Basic | Tested but Limited | Production-like | Fully Optimized |
Security Controls | Minimal | Basic | Moderate | Near-Production | Maximum |
Monitoring | Development Tools, Logs | Basic Monitoring | Test Monitoring | Full Monitoring Suite | Comprehensive Production Monitoring |
Cost Optimization | Not Prioritized | Limited | Moderate | Similar to Production | Highly Optimized |
Availability Target | During Work Hours | 8/5 or On-demand | 8/5 or Scheduled | Near 24/7 | 24/7 High Availability |
Environment Naming Conventions
Organizations often use different terminology for similar environments. Here are common naming variations:
Environment Naming Conventions
Different industries and organizations use varied terminology to describe similar environment types.
- Standard Names
- Alternative Names
- Numeric Schemes
- Other Variations
- Development (Dev): Individual developer environments or shared development servers
- Integration: Where code is merged and initially tested together
- Test/QA: Dedicated environment for quality assurance testing
- Staging/Pre-production: Final validation environment before production
- Production (Prod): Live environment serving real users
- Development: Also called "Local," "Dev Box," or "Sandbox"
- Integration: Also called "Build," "CI Environment," or "Dev Integration"
- Test/QA: Also called "QA," "SIT" (System Integration Testing), or "Test"
- Staging: Also called "Pre-Prod," "UAT" (User Acceptance Testing), "Stage," or "Model Office"
- Production: Also called "Prod," "Live," "Public," or "Customer-Facing"
Some organizations use numbered environments instead of descriptive names:
- Development: ENV0, E0, or DEV
- Integration: ENV1, E1, or INT
- Test/QA: ENV2, E2, or TST
- Staging: ENV3, E3, or STG
- Production: ENV4, E4, or PRD
Cloud providers might use similar numbered schemes for deployment slots or environment tiers.
Additional environment types that may exist in some organizations:
- Demo: Customer demonstration environment with sample data
- Training: Environment configured for training new users
- Disaster Recovery (DR): Backup production environment for business continuity
- Performance: Specialized environment for load and performance testing
- Security: Dedicated environment for security testing and penetration testing
- Sandbox: Isolated environment for experimental development
Environment Promotion Flow
Legend
Components
Connection Types
Configuration Across Environments
How Settings Change Across Environments
Think of environment configurations like different settings for the same vehicle in different situations:
- Development: Like a car in a mechanic's garage - panels open, diagnostic tools attached, easy to access all parts, but not ready for the road.
- Testing: Like a car on a test track - safety features active but with special monitoring equipment attached to measure performance.
- Staging: Like the final inspection before delivery - everything configured exactly as it would be for the customer, but in a controlled setting.
- Production: Like a car on the public road - fully secured, optimized for performance and safety, with restricted access to internal systems.
Key differences between environments typically include:
- External Connections: Where the application gets data from (test databases vs. real ones)
- Security Settings: How tightly locked-down the system is
- Performance Settings: How the system balances speed and resource usage
- Monitoring: How much information is collected about the system's operation
- Access Controls: Who can make changes and how those changes are approved
Environment Infrastructure Examples
Modern environments are typically implemented using infrastructure as code. Here are simplified examples of how different environments might be defined:
Think of environment infrastructure like building the same house in different locations, each with specific purposes:
- Development Environment: Like a model home used by architects and designers - smaller scale, frequently changed, and designed for experimentation rather than permanent occupancy
- Testing Environment: Like a home inspection site - built to match the final design but with special access points for inspectors to validate everything works correctly
- Staging Environment: Like a fully furnished show home that potential buyers can tour - looks and functions exactly like the real thing but isn't actually being lived in
- Production Environment: The actual homes where customers live - fully functional, secure, and optimized for daily use
The infrastructure code examples below show how we can build essentially the same structure but with different characteristics (size, security, cost) based on its purpose. This approach:
- Reduces cost by using smaller resources for non-production environments
- Improves security by applying stricter controls in production
- Enhances reliability by ensuring consistent architecture across all environments
- Accelerates delivery by making environment creation repeatable and automated
Environment Infrastructure Examples
These examples demonstrate how infrastructure-as-code tools can implement environment-specific configurations.
- AWS CloudFormation
- Terraform
- Docker Compose
- Kubernetes
# Development Environment
AWSTemplateFormatVersion: '2010-09-09'
Parameters:
EnvironmentType:
Type: String
Default: Development
AllowedValues: [Development, Integration, Testing, Staging, Production]
Resources:
WebServerInstance:
Type: AWS::EC2::Instance
Properties:
InstanceType: !If [IsProduction, t3.large, t3.small]
ImageId: ami-0c55b159cbfafe1f0
Tags:
- Key: Environment
Value: !Ref EnvironmentType
Conditions:
IsProduction: !Equals [!Ref EnvironmentType, Production]
IsStaging: !Equals [!Ref EnvironmentType, Staging]
# Different logging and monitoring based on environment type
Outputs:
WebsiteURL:
Value: !GetAtt WebServerInstance.PublicDnsName
# Define variables for different environments
variable "environment" {
type = string
default = "development"
}
locals {
# Environment-specific configurations
env_configs = {
development = {
instance_type = "t2.micro"
instance_count = 1
enable_logging = true
debug_mode = true
}
staging = {
instance_type = "t2.medium"
instance_count = 2
enable_logging = true
debug_mode = false
}
production = {
instance_type = "t2.large"
instance_count = 3
enable_logging = true
debug_mode = false
}
}
# Use the configuration for the current environment
config = local.env_configs[var.environment]
}
resource "aws_instance" "web" {
count = local.config.instance_count
ami = "ami-0c55b159cbfafe1f0"
instance_type = local.config.instance_type
tags = {
Name = "WebServer-${var.environment}-${count.index}"
Environment = var.environment
}
}
version: '3'
services:
webapp:
image: myapp:latest
environment:
- NODE_ENV=${ENVIRONMENT:-development}
- LOG_LEVEL=${LOG_LEVEL:-debug}
- DB_HOST=${DB_HOST:-db}
- DB_USER=${DB_USER:-devuser}
- DB_PASSWORD=${DB_PASSWORD:-devpassword}
ports:
- "3000:3000"
volumes:
# Development-only volume mounts
- ${MOUNT_SOURCE_CODE:-./src:/app/src}
networks:
- app-network
db:
image: postgres:13
environment:
- POSTGRES_USER=${DB_USER:-devuser}
- POSTGRES_PASSWORD=${DB_PASSWORD:-devpassword}
- POSTGRES_DB=${DB_NAME:-myapp}
volumes:
- ${DB_DATA_PATH:-./data/db:/var/lib/postgresql/data}
networks:
- app-network
networks:
app-network:
driver: bridge
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
namespace: ${ENVIRONMENT}
spec:
replicas: ${REPLICAS}
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
environment: ${ENVIRONMENT}
spec:
containers:
- name: myapp
image: myapp:${VERSION}
ports:
- containerPort: 8080
env:
- name: SPRING_PROFILES_ACTIVE
value: ${ENVIRONMENT}
- name: LOG_LEVEL
value: ${LOG_LEVEL}
resources:
requests:
memory: "${MEMORY_REQUEST}"
cpu: "${CPU_REQUEST}"
limits:
memory: "${MEMORY_LIMIT}"
cpu: "${CPU_LIMIT}"
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: ${LIVENESS_DELAY}
periodSeconds: 10
---
apiVersion: v1
kind: ConfigMap
metadata:
name: myapp-config
namespace: ${ENVIRONMENT}
data:
application.properties: |
server.port=8080
spring.datasource.url=jdbc:postgresql://${DB_HOST}/${DB_NAME}
# Environment-specific settings
feature.newfeature.enabled=${FEATURE_FLAG_ENABLED}
logging.level.root=${LOG_LEVEL}
Best Practices for Environment Management
Practical Environment Management Advice
- Keep Things Consistent: Make all environments as similar as possible to avoid surprises when moving from testing to production.
- Write Everything Down: Document how each environment is set up and what makes it different from others.
- Automate Setup: Use scripts and tools to set up environments automatically instead of manual configuration.
- Create When Needed: For some testing environments, create them on-demand and delete them when finished to save resources.
- Restrict Access: Limit who can make changes to each environment, with stricter controls as you get closer to production.
- Plan for Rollbacks: Have a strategy to quickly revert to a working state if something goes wrong after deployment.
- Watch Everything: Set up monitoring to alert you when something starts to go wrong in any environment.
- Test Configuration Changes: Check that settings changes work correctly before applying them to environments that customers use.
- Keep Secrets Secure: Store passwords and sensitive information securely and differently for each environment.
- Document Differences: Clearly record what's intentionally different between environments and why.
Common Environment Challenges
Organizations often face these challenges when managing multiple environments:
Common Environment Management Challenges
These challenges frequently arise when managing multiple environments across an organization.
- Configuration Drift
- Environment Costs
- Data Management
- Access Control
The Problem of Configuration Drift
Configuration drift occurs when environments that should be identical develop differences over time, typically due to manual changes or incomplete automation.
Signs of Configuration Drift:
- Code that works in one environment but fails in another despite being identical
- "It works on my machine" syndrome among developers
- Deployment failures that are difficult to diagnose
- Inconsistent performance or behavior across environments
Solutions:
- Infrastructure as Code: Define all environment configurations in code that can be version-controlled
- Immutable Infrastructure: Never modify running systems; instead, replace them with new deployments
- Environment Validation: Implement automated checks to verify environment consistency
- Configuration Auditing: Regularly scan and compare configurations across environments
Managing Environment Costs
Maintaining multiple environments can become expensive, especially when lower environments match production in scale.
Cost Challenges:
- Development and test environments that are rarely turned off
- Over-provisioned resources in non-production environments
- Duplicated data storage costs across environments
- License costs multiplied across environments
Solutions:
- Right-sizing: Scale non-production environments appropriately (smaller than production)
- Auto-scaling: Implement automatic scaling based on actual usage
- Scheduling: Automatically shut down development and testing environments during off-hours
- Ephemeral Environments: Create short-lived environments only when needed
- Resource Sharing: Use shared services for non-critical environment components
- Storage Tiering: Use lower-cost storage options for non-production data
Environment Data Challenges
Managing data across environments presents security, privacy, and practical challenges.
Data Challenges:
- Using production data in non-production environments (privacy and compliance risks)
- Creating realistic test data that reflects production scenarios
- Synchronizing databases across environments
- Managing different data volumes (production may have terabytes, but development needs a subset)
Solutions:
- Data Masking: Obfuscate sensitive information when copying from production to lower environments
- Synthetic Data Generation: Create realistic test data without using actual customer information
- Data Subsetting: Use representative samples rather than full datasets in lower environments
- Database Snapshots: Create point-in-time copies with automation for refreshes
- Data Migration Tools: Automate the process of preparing and moving data between environments
Environment Access Management
Balancing security with developer productivity when managing access to different environments.
Access Challenges:
- Providing developers sufficient access to troubleshoot issues without compromising security
- Managing different permission levels across environments
- Handling emergency access to production systems
- Auditing and tracking who made changes to each environment
Solutions:
- Role-Based Access Control (RBAC): Define specific permissions based on job functions
- Just-In-Time Access: Grant temporary elevated permissions only when needed
- Approval Workflows: Require peer approval for sensitive changes
- Session Recording: Log all activities during privileged access sessions
- Bastion Hosts/Jump Boxes: Provide controlled entry points to sensitive environments
- Federated Identity: Integrate with enterprise identity systems for consistent access control
Summary
Software environments are like a series of quality checkpoints that code passes through before reaching customers:
- Each environment serves a specific purpose, from initial development to final delivery
- The process gets more strict and controlled as code moves closer to production
- Different names might be used for similar environments in different organizations
- Settings and configurations change between environments to match their purpose
- Modern approaches use automation to set up environments consistently
- Data handling becomes more careful and secure as you move toward production
- Access to make changes becomes more restricted in environments closer to production
This structured approach helps teams deliver reliable software by catching issues early when they're easier and less expensive to fix.
Additional Resources
- The Phoenix Project - A novel about IT, DevOps, and helping your business win
- 12 Factor App - A methodology for building modern, scalable applications
- Infrastructure as Code - Principles and practices for managing environments as code