From 793a46ba45229cf26c67d760c4b1df767a9e0f12 Mon Sep 17 00:00:00 2001 From: Daniel Roy Greenfeld Date: Mon, 15 Jan 2018 12:33:51 -0800 Subject: [PATCH] Removed expiramental elastic beanstalk support and bumped official Django version to 1.11.9 --- CHANGELOG.md | 4 + LICENSE | 2 +- README.rst | 2 - cookiecutter.json | 1 - docs/deployment-with-elastic-beanstalk.rst | 75 ----------------- docs/index.rst | 1 - hooks/post_gen_project.py | 80 +++++++++---------- hooks/pre_gen_project.py | 6 +- setup.py | 2 +- .../.ebextensions/10_packages.config | 7 -- .../.ebextensions/20_elasticcache.config | 46 ----------- .../.ebextensions/30_options.config | 6 -- .../.ebextensions/40_python.config | 17 ---- .../.ebextensions/50_apache.config | 3 - .../.ebextensions/enable_mod_deflate.conf | 25 ------ {{cookiecutter.project_slug}}/README.rst | 9 --- .../config/settings/production.py | 25 +----- {{cookiecutter.project_slug}}/ebsetenv.py | 37 --------- 18 files changed, 46 insertions(+), 302 deletions(-) delete mode 100644 docs/deployment-with-elastic-beanstalk.rst delete mode 100644 {{cookiecutter.project_slug}}/.ebextensions/10_packages.config delete mode 100644 {{cookiecutter.project_slug}}/.ebextensions/20_elasticcache.config delete mode 100644 {{cookiecutter.project_slug}}/.ebextensions/30_options.config delete mode 100644 {{cookiecutter.project_slug}}/.ebextensions/40_python.config delete mode 100644 {{cookiecutter.project_slug}}/.ebextensions/50_apache.config delete mode 100644 {{cookiecutter.project_slug}}/.ebextensions/enable_mod_deflate.conf delete mode 100644 {{cookiecutter.project_slug}}/ebsetenv.py diff --git a/CHANGELOG.md b/CHANGELOG.md index c40bb26b..24f8d11c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ All enhancements and patches to Cookiecutter Django will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). +## [2018-01-15] +### Changed +- Removed Elastic Beanstalk support (@pydanny) + ## [2017-12-28] ### Changed - Upgraded to Django 1.11 (@pydanny) diff --git a/LICENSE b/LICENSE index 9a5d2fc0..da2bbe30 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2013-2016, Daniel Greenfeld +Copyright (c) 2013-2018, Daniel Greenfeld All rights reserved. Redistribution and use in source and binary forms, with or without modification, diff --git a/README.rst b/README.rst index 838253f4..35a8bc42 100644 --- a/README.rst +++ b/README.rst @@ -51,7 +51,6 @@ Features * Instructions for deploying to PythonAnywhere_ * Run tests with unittest or py.test * Customizable PostgreSQL version -* Experimental support for Amazon Elastic Beanstalk .. _`maintained Foundation fork`: https://github.com/Parbhat/cookiecutter-django-foundation @@ -185,7 +184,6 @@ Answer the prompts with your own desired options_. For example:: 4 - Apache Software License 2.0 5 - Not open source Choose from 1, 2, 3, 4, 5 [1]: 1 - use_elasticbeanstalk_experimental: n Enter the project and take a look around:: diff --git a/cookiecutter.json b/cookiecutter.json index 184e8796..933c3dfa 100644 --- a/cookiecutter.json +++ b/cookiecutter.json @@ -16,7 +16,6 @@ "windows": "n", "use_docker": "n", "use_heroku": "n", - "use_elasticbeanstalk_experimental": "n", "use_compressor": "n", "postgresql_version": ["10", "9.6", "9.5", "9.4", "9.3", "9.2"], "js_task_runner": ["Gulp", "Grunt", "None"], diff --git a/docs/deployment-with-elastic-beanstalk.rst b/docs/deployment-with-elastic-beanstalk.rst deleted file mode 100644 index d481c93b..00000000 --- a/docs/deployment-with-elastic-beanstalk.rst +++ /dev/null @@ -1,75 +0,0 @@ -Deployment with Elastic Beanstalk -========================================== - -.. index:: Elastic Beanstalk - -Warning: Experimental ---------------------- - -This is experimental. For the time being there will be bugs and issues. If you've never used Elastic Beanstalk before, please hold off before trying this option. - -On the other hand, we need help cleaning this up. If you do have knowledge of Elastic Beanstalk, we would appreciate the help. :) - -Prerequisites -------------- - -* awsebcli - -Instructions -------------- - -If you haven't done so, create a directory of environments:: - - eb init -p python3.4 MY_PROJECT_SLUG - # Warning: If you use python3.6, you will run into problems later due to some incompatibility with - # mod_wgsi 3.5 (packaged in 64bit Amazon Linux 2017.09 v2.6.1 running Python 3.6). See: - # https://serverfault.com/questions/884469/mod-wsgi-call-to-site-addsitedir-failed-on-aws-elastic-beanstalk-python-3/885445 - -Replace `MY_PROJECT_SLUG` with the value you entered for `project_slug`. - -Once that is done, create the environment (server) where the app will run:: - - eb create MY_PROJECT_SLUG - # Note: This will eventually fail on a postgres error, because postgres doesn't exist yet - -Now make sure you are in the right environment:: - - eb list - -If you are not in the right environment, then put yourself in the correct one:: - - eb use MY_PROJECT_SLUG - -Set the environment variables. Notes: You will be prompted if the `.env` file is missing. The script will ignore any PostgreSQL values, as RDS uses it's own system:: - - # Set the environment variables - python ebsetenv.py - -Speaking of PostgreSQL, go to the Elasting Beanstalk configuration panel for RDS. Create new RDS database, with these attributes: - -* PostgreSQL -* Version 9.4.9 -* Size db.t2.micro (You can upgrade later) - -(Get some coffee, this is going to take a while) - -Once you have a database specified, deploy again so your instance can pick up the new PostgreSQL values:: - - eb deploy - -Take a look:: - - eb open - -FAQ ------ - -Why Not Use Docker on Elastic Beanstalk? -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Because I didn't want to add an abstraction (Docker) on top of an abstraction (Elastic Beanstalk) on top of an abstraction (Cookiecutter Django). - -Why Can't I Use Both Docker/Heroku with Elastic Beanstalk? -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Because the environment variables that our Docker and Heroku setups use for PostgreSQL access is different then how Amazon RDS handles this access. At this time we're just trying to get things to work reliably with Elastic Beanstalk, and full integration will come later. diff --git a/docs/index.rst b/docs/index.rst index 3b0a268c..41a1138f 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -25,7 +25,6 @@ Contents: faq troubleshooting my-favorite-cookie - deployment-with-elastic-beanstalk Indices and tables ================== diff --git a/hooks/post_gen_project.py b/hooks/post_gen_project.py index b383e419..6a9df04f 100644 --- a/hooks/post_gen_project.py +++ b/hooks/post_gen_project.py @@ -12,6 +12,7 @@ A portion of this code was adopted from Django's standard crypto functions and utilities, specifically: https://github.com/django/django/blob/master/django/utils/crypto.py """ +from __future__ import print_function import os import random import shutil @@ -119,8 +120,6 @@ def remove_heroku_files(): Removes files needed for heroku if it isn't going to be used """ filenames = ["Procfile", "runtime.txt"] - if '{{ cookiecutter.use_elasticbeanstalk_experimental }}'.lower() != 'y': - filenames.append("requirements.txt") for filename in ["Procfile", "runtime.txt"]: file_name = os.path.join(PROJECT_DIRECTORY, filename) remove_file(file_name) @@ -130,7 +129,7 @@ def remove_docker_files(): """ Removes files needed for docker if it isn't going to be used """ - for filename in ["local.yml", "production.yml", ".dockerignore"]: + for filename in ["dev.yml", "docker-compose.yml", ".dockerignore"]: os.remove(os.path.join( PROJECT_DIRECTORY, filename )) @@ -167,6 +166,14 @@ def remove_packageJSON_file(): PROJECT_DIRECTORY, filename )) +def remove_certbot_files(): + """ + Removes files needed for certbot if it isn't going to be used + """ + nginx_dir_location = os.path.join(PROJECT_DIRECTORY, 'compose/nginx') + for filename in ["nginx-secure.conf", "start.sh", "dhparams.example.pem"]: + file_name = os.path.join(nginx_dir_location, filename) + remove_file(file_name) def remove_copying_files(): """ @@ -177,31 +184,6 @@ def remove_copying_files(): PROJECT_DIRECTORY, filename )) -def remove_elasticbeanstalk(): - """ - Removes elastic beanstalk components - """ - docs_dir_location = os.path.join(PROJECT_DIRECTORY, '.ebextensions') - if os.path.exists(docs_dir_location): - shutil.rmtree(docs_dir_location) - - filenames = ["ebsetenv.py", ] - if '{{ cookiecutter.use_heroku }}'.lower() != 'y': - filenames.append("requirements.txt") - for filename in filenames: - os.remove(os.path.join( - PROJECT_DIRECTORY, filename - )) - -def remove_open_source_files(): - """ - Removes files conventional to opensource projects only. - """ - for filename in ["CONTRIBUTORS.txt"]: - os.remove(os.path.join( - PROJECT_DIRECTORY, filename - )) - # IN PROGRESS # def copy_doc_files(project_directory): @@ -221,26 +203,26 @@ def remove_open_source_files(): # dst = os.path.join(target_dir, name) # shutil.copyfile(src, dst) -# Generates and saves random secret key +# 1. Generates and saves random secret key make_secret_key(PROJECT_DIRECTORY) -# Removes the taskapp if celery isn't going to be used +# 2. Removes the taskapp if celery isn't going to be used if '{{ cookiecutter.use_celery }}'.lower() == 'n': remove_task_app(PROJECT_DIRECTORY) -# Removes the .idea directory if PyCharm isn't going to be used +# 3. Removes the .idea directory if PyCharm isn't going to be used if '{{ cookiecutter.use_pycharm }}'.lower() != 'y': remove_pycharm_dir(PROJECT_DIRECTORY) -# Removes all heroku files if it isn't going to be used +# 4. Removes all heroku files if it isn't going to be used if '{{ cookiecutter.use_heroku }}'.lower() != 'y': remove_heroku_files() -# Removes all docker files if it isn't going to be used +# 5. Removes all docker files if it isn't going to be used if '{{ cookiecutter.use_docker }}'.lower() != 'y': remove_docker_files() -# Removes all JS task manager files if it isn't going to be used +# 6. Removes all JS task manager files if it isn't going to be used if '{{ cookiecutter.js_task_runner}}'.lower() == 'gulp': remove_grunt_files() elif '{{ cookiecutter.js_task_runner}}'.lower() == 'grunt': @@ -250,7 +232,11 @@ else: remove_grunt_files() remove_packageJSON_file() -# Display a warning if use_docker and use_grunt are selected. Grunt isn't +# 7. Removes all certbot/letsencrypt files if it isn't going to be used +if '{{ cookiecutter.use_lets_encrypt }}'.lower() != 'y': + remove_certbot_files() + +# 8. Display a warning if use_docker and use_grunt are selected. Grunt isn't # supported by our docker config atm. if '{{ cookiecutter.js_task_runner }}'.lower() in ['grunt', 'gulp'] and '{{ cookiecutter.use_docker }}'.lower() == 'y': print( @@ -259,15 +245,21 @@ if '{{ cookiecutter.js_task_runner }}'.lower() in ['grunt', 'gulp'] and '{{ cook "js task runner service to your docker configuration manually." ) +# 9. Removes the certbot/letsencrypt files and display a warning if use_lets_encrypt is selected and use_docker isn't. +if '{{ cookiecutter.use_lets_encrypt }}'.lower() == 'y' and '{{ cookiecutter.use_docker }}'.lower() != 'y': + remove_certbot_files() + print( + "You selected to use Let's Encrypt and didn't select to use docker. This is NOT supported out of the box for now. You " + "can continue to use the project like you normally would, but Let's Encrypt files have been included." + ) -# Removes files needed for the GPLv3 licence if it isn't going to be used. +# 10. Directs the user to the documentation if certbot and docker are selected. +if '{{ cookiecutter.use_lets_encrypt }}'.lower() == 'y' and '{{ cookiecutter.use_docker }}'.lower() == 'y': + print( + "You selected to use Let's Encrypt, please see the documentation for instructions on how to use this in production. " + "You must generate a dhparams.pem file before running docker-compose in a production environment." + ) + +# 11. Removes files needed for the GPLv3 licence if it isn't going to be used. if '{{ cookiecutter.open_source_license}}' != 'GPLv3': remove_copying_files() - -# Remove Elastic Beanstalk files -if '{{ cookiecutter.use_elasticbeanstalk_experimental }}'.lower() != 'y': - remove_elasticbeanstalk() - -# Remove files conventional to opensource projects only. -if '{{ cookiecutter.open_source_license }}' == 'Not open source': - remove_open_source_files() diff --git a/hooks/pre_gen_project.py b/hooks/pre_gen_project.py index c7a68450..5f2c9d5d 100644 --- a/hooks/pre_gen_project.py +++ b/hooks/pre_gen_project.py @@ -3,13 +3,9 @@ project_slug = '{{ cookiecutter.project_slug }}' if hasattr(project_slug, 'isidentifier'): assert project_slug.isidentifier(), 'Project slug should be valid Python identifier!' -elasticbeanstalk = '{{ cookiecutter.use_elasticbeanstalk_experimental }}'.lower() heroku = '{{ cookiecutter.use_heroku }}'.lower() docker = '{{ cookiecutter.use_docker }}'.lower() -if elasticbeanstalk == 'y' and (heroku == 'y' or docker == 'y'): - raise Exception("Cookiecutter Django's EXPERIMENTAL Elastic Beanstalk support is incompatible with Heroku and Docker setups.") - if docker == 'n': import sys @@ -26,6 +22,6 @@ if docker == 'n': elif choice in yes_options: pass else: - sys.stdout.write("Please respond with %s or %s" + sys.stdout.write("Please respond with %s or %s" % (', '.join([o for o in yes_options if not o == '']) , ', '.join([o for o in no_options if not o == '']))) diff --git a/setup.py b/setup.py index a300dc7f..eb5856e6 100644 --- a/setup.py +++ b/setup.py @@ -10,7 +10,7 @@ except ImportError: # Our version ALWAYS matches the version of Django we support # If Django has a new release, we branch, tag, then update this setting after the tag. -version = '1.11.8' +version = '1.11.9' if sys.argv[-1] == 'tag': os.system('git tag -a %s -m "version %s"' % (version, version)) diff --git a/{{cookiecutter.project_slug}}/.ebextensions/10_packages.config b/{{cookiecutter.project_slug}}/.ebextensions/10_packages.config deleted file mode 100644 index 136be533..00000000 --- a/{{cookiecutter.project_slug}}/.ebextensions/10_packages.config +++ /dev/null @@ -1,7 +0,0 @@ -packages: - yum: - git: [] - postgresql94-devel: [] - libjpeg-turbo-devel: [] - libffi: [] - libffi-devel: [] diff --git a/{{cookiecutter.project_slug}}/.ebextensions/20_elasticcache.config b/{{cookiecutter.project_slug}}/.ebextensions/20_elasticcache.config deleted file mode 100644 index 26c059e3..00000000 --- a/{{cookiecutter.project_slug}}/.ebextensions/20_elasticcache.config +++ /dev/null @@ -1,46 +0,0 @@ -#This sample requires you to create a separate configuration file that defines the custom -# option settings for CacheCluster properties. - -Resources: - MyCacheSecurityGroup: - Type: "AWS::EC2::SecurityGroup" - Properties: - GroupDescription: "Lock cache down to webserver access only" - SecurityGroupIngress : - - IpProtocol : "tcp" - FromPort : - Fn::GetOptionSetting: - OptionName : "CachePort" - DefaultValue: "6379" - ToPort : - Fn::GetOptionSetting: - OptionName : "CachePort" - DefaultValue: "6379" - SourceSecurityGroupName: - Ref: "AWSEBSecurityGroup" - MyElastiCache: - Type: "AWS::ElastiCache::CacheCluster" - Properties: - CacheNodeType: - Fn::GetOptionSetting: - OptionName : "CacheNodeType" - DefaultValue : "cache.t2.micro" - NumCacheNodes: - Fn::GetOptionSetting: - OptionName : "NumCacheNodes" - DefaultValue : "1" - Engine: - Fn::GetOptionSetting: - OptionName : "Engine" - DefaultValue : "redis" - VpcSecurityGroupIds: - - - Fn::GetAtt: - - MyCacheSecurityGroup - - GroupId - -Outputs: - ElastiCache: - Description : "ID of ElastiCache Cache Cluster with Redis Engine" - Value : - Ref : "MyElastiCache" diff --git a/{{cookiecutter.project_slug}}/.ebextensions/30_options.config b/{{cookiecutter.project_slug}}/.ebextensions/30_options.config deleted file mode 100644 index fefec489..00000000 --- a/{{cookiecutter.project_slug}}/.ebextensions/30_options.config +++ /dev/null @@ -1,6 +0,0 @@ -option_settings: - "aws:elasticbeanstalk:customoption": - CacheNodeType : cache.t2.micro - NumCacheNodes : 1 - Engine : redis - CachePort : 6379 diff --git a/{{cookiecutter.project_slug}}/.ebextensions/40_python.config b/{{cookiecutter.project_slug}}/.ebextensions/40_python.config deleted file mode 100644 index 03b91eb4..00000000 --- a/{{cookiecutter.project_slug}}/.ebextensions/40_python.config +++ /dev/null @@ -1,17 +0,0 @@ -container_commands: - 01_migrate: - command: "source /opt/python/run/venv/bin/activate && python manage.py migrate --noinput" - leader_only: True - 02_collectstatic: - command: "source /opt/python/run/venv/bin/activate && python manage.py collectstatic --noinput" -option_settings: - "aws:elasticbeanstalk:application:environment": - DJANGO_SETTINGS_MODULE: "config.settings.production" - REDIS_ENDPOINT_ADDRESS: '`{ "Fn::GetAtt" : [ "MyElastiCache", "RedisEndpoint.Address"]}`' - REDIS_PORT: '`{ "Fn::GetAtt" : [ "MyElastiCache", "RedisEndpoint.Port"]}`' - "aws:elasticbeanstalk:container:python": - WSGIPath: config/wsgi.py - NumProcesses: 3 - NumThreads: 20 - "aws:elasticbeanstalk:container:python:staticfiles": - "/static/": "www/static/" diff --git a/{{cookiecutter.project_slug}}/.ebextensions/50_apache.config b/{{cookiecutter.project_slug}}/.ebextensions/50_apache.config deleted file mode 100644 index 672cb625..00000000 --- a/{{cookiecutter.project_slug}}/.ebextensions/50_apache.config +++ /dev/null @@ -1,3 +0,0 @@ -container_commands: - 01_setup_apache: - command: "cp .ebextensions/enable_mod_deflate.conf /etc/httpd/conf.d/enable_mod_deflate.conf" diff --git a/{{cookiecutter.project_slug}}/.ebextensions/enable_mod_deflate.conf b/{{cookiecutter.project_slug}}/.ebextensions/enable_mod_deflate.conf deleted file mode 100644 index 7a77cc23..00000000 --- a/{{cookiecutter.project_slug}}/.ebextensions/enable_mod_deflate.conf +++ /dev/null @@ -1,25 +0,0 @@ -# mod_deflate configuration - - # Restrict compression to these MIME types - AddOutputFilterByType DEFLATE text/plain - AddOutputFilterByType DEFLATE text/html - AddOutputFilterByType DEFLATE application/xhtml+xml - AddOutputFilterByType DEFLATE text/xml - AddOutputFilterByType DEFLATE application/xml - AddOutputFilterByType DEFLATE application/xml+rss - AddOutputFilterByType DEFLATE application/x-javascript - AddOutputFilterByType DEFLATE text/javascript - AddOutputFilterByType DEFLATE text/css - # Level of compression (Highest 9 - Lowest 1) - DeflateCompressionLevel 9 - # Netscape 4.x has some problems. - BrowserMatch ^Mozilla/4 gzip-only-text/html - # Netscape 4.06-4.08 have some more problems - BrowserMatch ^Mozilla/4\.0[678] no-gzip - # MSIE masquerades as Netscape, but it is fine - BrowserMatch \bMSI[E] !no-gzip !gzip-only-text/html - - # Make sure proxies don't deliver the wrong content - Header append Vary User-Agent env=!dont-vary - - diff --git a/{{cookiecutter.project_slug}}/README.rst b/{{cookiecutter.project_slug}}/README.rst index c4bf9fe3..06dd82ed 100644 --- a/{{cookiecutter.project_slug}}/README.rst +++ b/{{cookiecutter.project_slug}}/README.rst @@ -132,16 +132,7 @@ See detailed `cookiecutter-django Docker documentation`_. .. _`cookiecutter-django Docker documentation`: http://cookiecutter-django.readthedocs.io/en/latest/deployment-with-docker.html {% endif %} -{% if cookiecutter.use_elasticbeanstalk_experimental.lower() == 'y' %} -Elastic Beanstalk -~~~~~~~~~~~~~~~~~~ - -See detailed `cookiecutter-django Elastic Beanstalk documentation`_. - -.. _`cookiecutter-django Elastic Beanstalk documentation`: http://cookiecutter-django.readthedocs.io/en/latest/deployment-with-elastic-beanstalk.html - -{% endif %} {% if cookiecutter.custom_bootstrap_compilation == "y" %} Custom Bootstrap Compilation ^^^^^^ diff --git a/{{cookiecutter.project_slug}}/config/settings/production.py b/{{cookiecutter.project_slug}}/config/settings/production.py index db581306..33542fbf 100644 --- a/{{cookiecutter.project_slug}}/config/settings/production.py +++ b/{{cookiecutter.project_slug}}/config/settings/production.py @@ -172,36 +172,17 @@ TEMPLATES[0]['OPTIONS']['loaders'] = [ {% set _DEFAULT_CONN_MAX_AGE=60 %} # DATABASE CONFIGURATION # ------------------------------------------------------------------------------ -{% if cookiecutter.use_elasticbeanstalk_experimental.lower() == 'y' -%} -# Uses Amazon RDS for database hosting, which doesn't follow the Heroku-style spec -DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.postgresql_psycopg2', - 'NAME': env('RDS_DB_NAME'), - 'USER': env('RDS_USERNAME'), - 'PASSWORD': env('RDS_PASSWORD'), - 'HOST': env('RDS_HOSTNAME'), - 'PORT': env('RDS_PORT'), - 'CONN_MAX_AGE': env.int('CONN_MAX_AGE', default={{ _DEFAULT_CONN_MAX_AGE }}), - } -} -{% else %} + # Use the Heroku-style specification # Raises ImproperlyConfigured exception if DATABASE_URL not in os.environ DATABASES['default'] = env.db('DATABASE_URL') DATABASES['default']['CONN_MAX_AGE'] = env.int('CONN_MAX_AGE', default={{ _DEFAULT_CONN_MAX_AGE }}) -{%- endif %} + # CACHING # ------------------------------------------------------------------------------ -{% if cookiecutter.use_elasticbeanstalk_experimental.lower() == 'y' -%} -REDIS_LOCATION = 'redis://{}:{}/0'.format( - env('REDIS_ENDPOINT_ADDRESS'), - env('REDIS_PORT') -) -{% else %} REDIS_LOCATION = '{0}/{1}'.format(env('REDIS_URL', default='redis://127.0.0.1:6379'), 0) -{%- endif %} + # Heroku URL does not pass the DB number, so we parse it in CACHES = { 'default': { diff --git a/{{cookiecutter.project_slug}}/ebsetenv.py b/{{cookiecutter.project_slug}}/ebsetenv.py deleted file mode 100644 index ba9652db..00000000 --- a/{{cookiecutter.project_slug}}/ebsetenv.py +++ /dev/null @@ -1,37 +0,0 @@ -"""Converts a .env file to Elastic Beanstalk environment variables""" - -import os -from sys import exit -from subprocess import check_call - -try: - import dotenv -except ImportError: - print("Please install the 'dotenv' library: 'pip install dotenv'") - exit() - -def main(): - if not os.path.exists('.env'): - print('ERROR!! .env file is missing!') - print("Please copy 'env.example' to '.env' and add appropriate values") - exit() - command = ['eb', 'setenv'] - failures = [] - for key, value in dotenv.Dotenv('.env').items(): - if key.startswith('POSTGRES'): - print('Skipping POSTGRES values - Amazon RDS provides these') - continue - if value: - command.append("{}={}".format(key, value)) - else: - failures.append(key) - if failures: - for failure in failures: - print("{} requires a value".format(failure)) - else: - print(' '.join(command)) - check_call(command) - - -if __name__ == '__main__': - main()