Environments
Environments in carlin enable multi-stage deployment workflows (development, staging, production) with automatic termination protection and environment-specific configurations.
Defining Environments
Specify environment using CLI option, environment variable, or config file:
CLI Option
carlin deploy --environment production
Environment Variable
CARLIN_ENVIRONMENT=staging carlin deploy
Config File
Create carlin.yml:
environment: staging
Deploy:
carlin deploy
Environment Benefits
1. Termination Protection
Stacks deployed with --environment automatically enable CloudFormation termination protection, preventing accidental deletion:
carlin deploy --environment production
# Stack created with termination protection enabled
carlin deploy --destroy --environment production
# Error: Cannot delete stack with termination protection
To delete protected stacks:
# Option 1: Remove environment flag and use stack name
carlin deploy --destroy --stack-name my-app-production
# Option 2: Disable protection in AWS Console first
2. Environment-Specific Naming
Environment name becomes part of the stack name:
carlin deploy --environment staging
# Stack: my-app-staging
carlin deploy --environment production
# Stack: my-app-production
This creates clear separation between environments without manual stack name management.
3. Environment-Specific Parameters
Use different CloudFormation parameters per environment:
# Staging with smaller instance
carlin deploy --environment staging --parameters '{"InstanceType":"t3.micro"}'
# Production with larger instance
carlin deploy --environment production --parameters '{"InstanceType":"t3.large"}'
4. Configuration Inheritance
Create environment-specific config files:
# carlin.yml (base configuration)
region: us-east-1
parameters:
DomainName: app.example.com
# carlin.staging.yml
environment: staging
parameters:
DomainName: staging.app.example.com
InstanceType: t3.micro
# carlin.production.yml
environment: production
parameters:
DomainName: app.example.com
InstanceType: t3.large
Deploy to specific environment:
carlin deploy --config carlin.staging.yml
carlin deploy --config carlin.production.yml
Common Environment Patterns
Three-Stage Pipeline
# 1. Development (feature branches, no environment)
git checkout feature/new-feature
carlin deploy
# Stack: my-app-feature-new-feature
# No termination protection
# 2. Staging (shared pre-production)
carlin deploy --environment staging
# Stack: my-app-staging
# Termination protection enabled
# 3. Production (live environment)
carlin deploy --environment production
# Stack: my-app-production
# Termination protection enabled
Environment-Based AWS Accounts
Use different AWS credentials per environment:
# Staging (AWS account 111111111111)
AWS_PROFILE=staging carlin deploy --environment staging
# Production (AWS account 222222222222)
AWS_PROFILE=production carlin deploy --environment production
CI/CD Integration
Configure GitHub Actions for automatic environment deployments:
# .github/workflows/deploy.yml
name: Deploy
on:
push:
branches:
- main
- staging
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Deploy to Staging
if: github.ref == 'refs/heads/staging'
run: carlin deploy --environment staging
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID_STAGING }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY_STAGING }}
- name: Deploy to Production
if: github.ref == 'refs/heads/main'
run: carlin deploy --environment production
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID_PROD }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY_PROD }}
Environment vs Branch Naming
See Stack Naming for the full naming algorithm.
Key difference: deploying with --environment enables termination protection and the environment name takes precedence over the branch name.
Environment Variables
Use CloudFormation parameters to pass environment-specific values:
carlin deploy --environment staging --parameters '{"Environment":"staging","DatabaseInstanceType":"db.t3.small"}'
Best Practices
- Always use
--environmentfor shared stages (staging, production) to enable termination protection - Separate AWS accounts for production when possible
- Use parameterized values instead of hardcoding environment-specific settings
- Document your environment setup in a README
Troubleshooting
Cannot Delete Environment Stack
Problem: Deletion fails with "Stack has termination protection enabled"
Solution: Use stack name without environment:
carlin deploy --destroy --stack-name my-app-production
Wrong Environment Deployed
Problem: Deployed to production instead of staging
Solution: Always explicitly set environment:
# Instead of relying on defaults
carlin deploy
# Always specify explicitly
carlin deploy --environment staging
Environment Variable Not Working
Problem: CARLIN_ENVIRONMENT not being recognized
Solution: Verify environment variable is exported:
export CARLIN_ENVIRONMENT=staging
echo $CARLIN_ENVIRONMENT # Should print: staging
carlin deploy
Related Topics
- Stack Naming - How environments affect stack names