环境属性未传递到Elastic Beanstalk中的应用程序 [英] Environment properties are not passed to application in Elastic Beanstalk
问题描述
部署我的Django项目时,未配置数据库设置,因为os.environ 中的'RDS_HOSTNAME'返回
false
.实际上,环境属性在部署时不可用.部署后,所有这些属性都可用.
正在运行/opt/elasticbeanstalk/bin/get-config环境
返回以下内容:
{"DJANGO_SETTINGS_MODULE":"myApp.settings","PYTHONPATH":"/var/app/venv/staging-LQM1lest/bin:$ PYTHONPATH","RDS_DB_NAME":ebdb","RDS_HOSTNAME":"xxxx.amazonaws.com","RDS_PASSWORD":"xxxx","RDS_PORT":"xxxx","RDS_USERNAME":"xxxx"
所有RDS前缀属性均已设置,但 os.environ
仍然无法读取.
setting.py
文件:
#[...]如果os.environ中的"RDS_HOSTNAME":数据库= {'默认': {'ENGINE':'django.db.backends.mysql','NAME':os.environ ['RDS_DB_NAME'],'USER':os.environ ['RDS_USERNAME'],'PASSWORD':os.environ ['RDS_PASSWORD'],'HOST':os.environ ['RDS_HOSTNAME'],'PORT':os.environ ['RDS_PORT'],}}#[...]
我是否需要进行任何更改以使这些属性在部署时可用?
似乎这是一个严重的错误,AWS对此并不在意.我想出了几种方法来完成这项工作,但所有这些方法都需要登录EB环境并进行一些手动工作.
解决方案1
如
2.在 settings.py
导入操作系统导入子流程进口ASTdef get_environ_vars():completed_process = subprocess.run(['/opt/elasticbeanstalk/bin/get-config','environment'],stdout = subprocess.PIPE,text = True,检查=真)返回ast.literal_eval(completed_process.stdout)
-
转到数据库"部分,并将其替换为该代码段
如果os.environ中的"RDS_HOSTNAME":数据库= {'默认': {'ENGINE':'django.db.backends.mysql','NAME':os.environ ['RDS_DB_NAME'],'USER':os.environ ['RDS_USERNAME'],'PASSWORD':os.environ ['RDS_PASSWORD'],'HOST':os.environ ['RDS_HOSTNAME'],'PORT':os.environ ['RDS_PORT'],}}别的:env_vars = get_environ_vars()数据库= {'默认': {'ENGINE':'django.db.backends.mysql','NAME':env_vars ['RDS_DB_NAME'],'USER':env_vars ['RDS_USERNAME'],'PASSWORD':env_vars ['RDS_PASSWORD'],'HOST':env_vars ['RDS_HOSTNAME'],'PORT':env_vars ['RDS_PORT'],}}
-
部署项目.
-
登录到环境(
eb ssh environment_name
). -
转到
/var/app/current/
目录并运行以下命令:source/var/app/venv/*/bin/activate
. -
最后运行
python3 manage.py migration
.
结论:
解决方案1 很少复杂,而秘密管理者又不是免费的(仅限30天试用期).
解决方案2 是最简单的之一,但我不建议 在EB上手动调整任何文件.
解决方案3 是我将使用的干净解决方案.此解决方案还将在以后解决此错误.
When deploying my Django project, database settings are not configured because 'RDS_HOSTNAME' in os.environ
returns false
. In fact not environment properties are available at the time of deployment. All these properties are available after the deployment.
Running /opt/elasticbeanstalk/bin/get-config environment
returns following:
{"DJANGO_SETTINGS_MODULE":"myApp.settings","PYTHONPATH":"/var/app/venv/staging-LQM1lest/bin:$PYTHONPATH","RDS_DB_NAME":"ebdb","RDS_HOSTNAME":"xxxx.amazonaws.com","RDS_PASSWORD":"xxxx","RDS_PORT":"xxxx","RDS_USERNAME":"xxxx"}
All RDS prefixed properties are set but still somehow os.environ
is unable to read it.
setting.py
file:
# [...]
if 'RDS_HOSTNAME' in os.environ:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': os.environ['RDS_DB_NAME'],
'USER': os.environ['RDS_USERNAME'],
'PASSWORD': os.environ['RDS_PASSWORD'],
'HOST': os.environ['RDS_HOSTNAME'],
'PORT': os.environ['RDS_PORT'],
}
}
# [...]
Do I have to make any changes to make these properties available at the time of deployment?
Seems like this is a serious bug and AWS doesn't care about it. There are few ways I came up with to make this work but all of them require logging into the EB environment and do some manual work.
Solution 1
As suggested in comment by hephalump
Create an AWS secret manager
Check
IAM instance profile
in EB's environmentConfiguration->Security->Edit
.Then go to IAM user console and go to
Roles
. From there you can attach policy to the instance profile for secret manager.Once it's done, deploy the project
Then login to the environment (
eb ssh environment_name
).Go to
/var/app/current/
directory and run this command:source /var/app/venv/*/bin/activate
.Finally run
python3 manage.py migrate
.
Solution 2
Edit
.bash_profile
and add export these variables at the end of the file:export RDS_DB_NAME=your_dbname export RDS_USERNAME=user export RDS_PASSWORD=pass export RDS_HOSTNAME=host_endpoint export RDS_PORT=3306
Run
source ~/.bash_profile
Now you can deploy your project.
Solution 3
- Set all environment properties in EB environment's configuration. (Go to
Configuration->Software->Edit->Environment properties
and add the key and values).
2. Add this snippet at the beginning of settings.py
from pathlib import Path
import os
import subprocess
import ast
def get_environ_vars():
completed_process = subprocess.run(
['/opt/elasticbeanstalk/bin/get-config', 'environment'],
stdout=subprocess.PIPE,
text=True,
check=True
)
return ast.literal_eval(completed_process.stdout)
Go to Database section and replace it with this snippet
if 'RDS_HOSTNAME' in os.environ: DATABASES = { 'default': { ' ENGINE': 'django.db.backends.mysql', 'NAME': os.environ['RDS_DB_NAME'], 'USER': os.environ['RDS_USERNAME'], 'PASSWORD': os.environ['RDS_PASSWORD'], 'HOST': os.environ['RDS_HOSTNAME'], 'PORT': os.environ['RDS_PORT'], } } else: env_vars = get_environ_vars() DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': env_vars['RDS_DB_NAME'], 'USER': env_vars['RDS_USERNAME'], 'PASSWORD': env_vars['RDS_PASSWORD'], 'HOST': env_vars['RDS_HOSTNAME'], 'PORT': env_vars['RDS_PORT'], } }
Deploy the project.
Login to the environment (
eb ssh environment_name
).Go to
/var/app/current/
directory and run this command:source /var/app/venv/*/bin/activate
.Finally run
python3 manage.py migrate
.
Conclusion:
Solution 1 is little complex and secret manager is not free (30 days trial only).
Solution 2 is simplest one but I do not recommend tempering any file manually on EB.
Solution 3 is a clean solution which I will use. This solution also takes care of this bug fix in future.
这篇关于环境属性未传递到Elastic Beanstalk中的应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!