A simple pip-installable tool for deploying Python applications to AWS Elastic Beanstalk. Perfect for solo developers and Python beginners who want to quickly ship their projects without spending days figuring out cloud deployment.
- Zero-config deployment with smart defaults (us-west-2, t4g.nano, etc.)
- Environment variable support via
.envfile with hybrid naming (LB_* with standard fallbacks) - Auto-OIDC -
securecommand detects OIDC env vars and configures authentication automatically - Both CLI and Python API for maximum flexibility
- One-command operations for deployment, HTTPS, OIDC auth, and cleanup
- Automatic change detection for environment updates
- Compatible with EB CLI - works alongside standard Elastic Beanstalk tools
- AWS credentials configured (
~/.aws/credentialsor environment variables) - Python 3.12 or newer
- A Dockerfile for your application
- An existing Python web application (or a new one) that you'd like to deploy
Install directly from GitHub using pip:
pip install git+https://github.com/bazeindustries/lazy-beanstalk.gitOr with pipx for isolated installation:
pipx install git+https://github.com/bazeindustries/lazy-beanstalk.gitOr with Poetry in your project:
poetry add git+https://github.com/bazeindustries/lazy-beanstalk.gitDeploy your application with a single command:
lb shipThat's it! Lazy Beanstalk will:
- Use your current directory name as the app name
- Create an environment named
{app-name}-env - Deploy to
us-west-2usingt4g.nanoinstances - Package and upload your application using the Dockerfile in your project root
- Create all necessary IAM roles and S3 buckets
- Output your application URL when complete
Enable HTTPS (auto-configures OIDC if env vars present):
lb secureOr add OIDC separately:
lb shieldClean up all resources:
lb scrapFor programmatic control, import and use the Python API:
from lazy_beanstalk import ship, secure, shield, scrap
# Deploy with custom configuration
result = ship(
app_name="my-app",
region="us-east-1",
instance_type="t3.small",
spot_instances=True,
min_instances=2,
max_instances=4,
env_vars={
"DATABASE_URL": "postgres://...",
"API_KEY": "secret"
},
tags={
"Environment": "production",
"Team": "platform"
}
)
print(f"Deployed to: {result['environment_url']}")
# Enable HTTPS
https_result = secure(
domain="api.example.com",
domain_mode="sub"
)
# Add authentication
auth_result = shield(
client_id="oauth-client-id",
client_secret="oauth-secret",
issuer="https://auth.example.com",
auth_endpoint="https://auth.example.com/authorize",
token_endpoint="https://auth.example.com/token",
userinfo_endpoint="https://auth.example.com/userinfo"
)
# Clean up
cleanup_result = scrap(force=True)Lazy Beanstalk uses sensible defaults for quick deployments:
- Region:
us-west-2 - Instance Type:
t4g.nano(ARM-based, cost-effective) - Autoscaling: Min 1, Max 1 instance
- Spot Instances: Disabled
- Load Balancer: Application Load Balancer
- Platform: Latest Amazon Linux 2023 Docker platform
- Tags:
Environment=development,ManagedBy=lazy-beanstalk
Configuration is merged from multiple sources (lowest to highest priority):
- Hardcoded defaults (see above)
- Environment variables (
.envfile, auto-loaded) - State file (
.elasticbeanstalk/config.yml) - API parameters or CLI flags
Lazy Beanstalk supports automatic .env file loading with smart separation of deployment vs application vars.
Best Practice Pattern (Recommended):
# .env - application vars (AUTO-PASSED to EB ✅)
DATABASE_URL=postgres://...
API_KEY=secret123
REDIS_URL=redis://...
# .env.lb - deployment vars only (NEVER passed to EB ❌)
AWS_REGION=us-west-2
LB_INSTANCE_TYPE=t4g.small
LB_SPOT_INSTANCES=true
LB_MIN_INSTANCES=2
LB_MAX_INSTANCES=4
LB_CERTIFICATE_ARN=arn:aws:acm:...
LB_DOMAIN_MODE=custom
LB_CUSTOM_SUBDOMAINS=api,admin,app
OIDC_CLIENT_ID=your-client-id
OIDC_CLIENT_SECRET=your-secret
OIDC_ISSUER=https://your-idp.com
OIDC_AUTH_ENDPOINT=https://your-idp.com/oauth2/authorize
OIDC_TOKEN_ENDPOINT=https://your-idp.com/oauth2/token
OIDC_USERINFO_ENDPOINT=https://your-idp.com/oauth2/userInfoHow It Works:
- All
.env*files are auto-loaded - Vars from
.env.lbare excluded (deployment config only) - Vars starting with
LB_prefix are excluded (deployment config only) - Everything else is passed to your EB application
- All
.env*files are excluded from the deployment bundle (never uploaded) - Your app reads vars via
os.getenv()in EB
Single File Option (using LB_ prefix for filtering):
# .env - everything in one file
DATABASE_URL=postgres://...
API_KEY=secret123
AWS_REGION=us-west-2 # ← Passed to EB
LB_INSTANCE_TYPE=t4g.small # ← NOT passed (LB_ prefix)
LB_OIDC_CLIENT_SECRET=secret # ← NOT passed (LB_ prefix)Custom Deployment File:
lb ship --deployment-env .env.deployment # Use this instead of .env.lbLazy Beanstalk stores state in .elasticbeanstalk/config.yml (EB CLI compatible) to:
- Track deployment configuration and detect changes
- Enable
eb logs,eb ssh, and other EB CLI commands - Store environment metadata
Lazy Beanstalk automatically creates IAM roles with AWS managed policies:
Service Role:
AWSElasticBeanstalkServiceAWSElasticBeanstalkEnhancedHealth
Instance Role:
AWSElasticBeanstalkWebTierAWSElasticBeanstalkMulticontainerDockerAWSElasticBeanstalkWorkerTier
Add custom policies by creating a directory with JSON policy files:
ship(policies_dir="./my-policies")Policy files in ./my-policies/*.json will be:
- Created as customer-managed IAM policies
- Attached to the EC2 instance role
- Synchronized on each deployment (1:1 local-to-cloud sync)
- Versioned in AWS (up to 5 versions maintained)
- Removed from AWS if deleted locally
Enable HTTPS using AWS Certificate Manager. If OIDC env vars are present, OIDC is auto-configured too:
# Via .env file (recommended)
# Add LB_CERTIFICATE_ARN, LB_DOMAIN_MODE, OIDC_* vars to .env
lb secure
# Or via CLI flags
lb secure --certificate-arn arn:aws:acm:... --domain-mode customDomain Modes:
sub: Creates{app-name}.example.comroot: Createsexample.comcustom: Creates multiple subdomains fromLB_CUSTOM_SUBDOMAINS=api,admin,app
Auto-configuration (via lb secure):
# Add OIDC vars to .env, then:
lb secure # Auto-configures OIDC if env vars presentStandalone (if not using auto-config):
# Via .env with OIDC_* vars
lb shield
# Or via CLI
lb shield --client-id <id> --client-secret <secret> --issuer <url> \
--auth-endpoint <url> --token-endpoint <url> --userinfo-endpoint <url>Deploy your application to AWS Elastic Beanstalk.
Options:
--app-name- Application name (default: current directory name)--environment-name- Environment name (default: {app-name}-env)--region- AWS region (default: us-west-2)--instance-type- EC2 instance type (default: t4g.nano)--spot/--no-spot- Use spot instances (default: no-spot)--min-instances- Min autoscaling instances (default: 1)--max-instances- Max autoscaling instances (default: 1)--policies-dir- Path to custom IAM policies directory--dockerfile-path- Path to Dockerfile (default: ./Dockerfile)--deployment-env- Deployment env file to exclude from EB (default: .env.lb)
Example:
lb ship --region us-east-1 --instance-type t3.small --spot --min-instances 2 --max-instances 4
lb ship --deployment-env .env.deployment # Use custom deployment fileEnable HTTPS with ACM and Route 53. Auto-configures OIDC if env vars present.
Options:
--certificate-arn- ACM certificate ARN (or use LB_CERTIFICATE_ARN env var)--domain-mode- Domain mode: sub, root, or custom (or use LB_DOMAIN_MODE env var)--custom-subdomains- Comma-separated subdomains for custom mode (or use LB_CUSTOM_SUBDOMAINS)--ttl- DNS record TTL (default: 300)
Example:
# Recommended: use .env file
lb secure
# Or via CLI
lb secure --certificate-arn arn:aws:acm:... --domain-mode custom --custom-subdomains api,adminConfigure OIDC authentication on the load balancer. Reads from env vars by default.
Options: All parameters optional if corresponding env vars are set (OIDC_CLIENT_ID, OIDC_CLIENT_SECRET, etc.):
--client-id,--client-secret,--issuer--auth-endpoint,--token-endpoint,--userinfo-endpoint--session-timeout- Session timeout in seconds (default: 36000)--scope- OIDC scope (default: openid)
Example:
# Recommended: use .env file with OIDC_* vars
lb shield
# Or use CLI
lb shield --client-id abc123 --client-secret xyz789 --issuer https://auth.example.com \
--auth-endpoint https://auth.example.com/authorize \
--token-endpoint https://auth.example.com/token \
--userinfo-endpoint https://auth.example.com/userinfoRemove all AWS resources created by lazy-beanstalk.
Options:
--app-name- Application name (default: from state file)--force- Skip confirmation prompts
Example:
lb scrap --forceDeploy application to AWS Elastic Beanstalk.
Parameters:
app_name(str): Application nameenvironment_name(str): Environment nameregion(str): AWS regioninstance_type(str): EC2 instance typespot_instances(bool): Use spot instancesmin_instances(int): Min autoscaling instancesmax_instances(int): Max autoscaling instancespolicies_dir(str): Path to custom IAM policies directoryenv_vars(dict): Environment variables for applicationtags(dict): AWS resource tagsdockerfile_path(str): Path to Dockerfileaws_profile(str): AWS profile name
Returns: Dict with deployment details (environment URL, app name, version, region)
Enable HTTPS on your Elastic Beanstalk environment. Auto-configures OIDC if env vars present.
Parameters:
certificate_arn(str): ACM certificate ARNdomain_mode(str): Domain mode (sub, root, custom)custom_subdomains(list): List of subdomains for custom modeinclude_root(bool): Include root domain in custom modettl(int): DNS record TTL
Returns: Dict with HTTPS configuration details (and OIDC if auto-configured)
Configure OIDC authentication.
Parameters:
client_id(str): OIDC client IDclient_secret(str): OIDC client secretissuer(str): OIDC issuer URLauth_endpoint(str): Authorization endpoint URLtoken_endpoint(str): Token endpoint URLuserinfo_endpoint(str): User info endpoint URLsession_timeout(int): Session timeout in secondssession_cookie_name(str): Session cookie namescope(str): OIDC scope
Returns: Dict with OIDC configuration details
Remove all AWS resources.
Parameters:
app_name(str): Application nameforce(bool): Skip confirmation prompts
Returns: Dict with cleanup status
- Cost Management: Application Load Balancers (required for HTTPS/OIDC) cost ~$16/month minimum
- Spot Instances: Can reduce costs by up to 90% but may be interrupted
- State File:
.elasticbeanstalk/directory tracked by lazy-beanstalk, compatible with EB CLI - Dockerfile Required: You must provide your own Dockerfile for complete runtime control
- Intended Use: Designed for prototypes, demos, and small personal tools
Lazy Beanstalk creates .elasticbeanstalk/config.yml, making it compatible with standard EB CLI commands:
eb status
eb logs
eb ssh
eb config
eb printenv# Just needs a Dockerfile
lb ship# .env file:
# AWS_REGION=us-east-1
# LB_INSTANCE_TYPE=t3.small
# LB_MIN_INSTANCES=2
# LB_MAX_INSTANCES=10
# LB_CERTIFICATE_ARN=arn:aws:acm:...
# OIDC_CLIENT_ID=...
# OIDC_CLIENT_SECRET=...
# OIDC_ISSUER=...
# OIDC_AUTH_ENDPOINT=...
# OIDC_TOKEN_ENDPOINT=...
# OIDC_USERINFO_ENDPOINT=...
lb ship && lb secure # Auto-configures OIDC from env varslb ship --spot --instance-type t4g.nano --region us-west-2lb scrap --forceEnsure you have a Dockerfile in your project root. Lazy Beanstalk requires you to provide your own Dockerfile.
Check the logs - Lazy Beanstalk detects and logs configuration changes. Some changes (like platform or load balancer type) require recreating the environment.
Ensure:
- Your ACM certificate is issued and validated
- The certificate domain matches your
--domainparameter - Your Route 53 hosted zone exists for the domain
Verify all required parameters are provided:
client_id,client_secret,issuerauth_endpoint,token_endpoint,userinfo_endpoint
Check environment variables or pass them explicitly.
Lazy Beanstalk was built with plenty of LLM assistance, particularly from Anthropic, Mistral and Continue.dev.