【问题标题】:Environment properties are not passed to application in Elastic Beanstalk环境属性不会传递给 Elastic Beanstalk 中的应用程序
【发布时间】:2021-02-07 21:47:06
【问题描述】:

部署我的 Django 项目时,未配置数据库设置,因为'RDS_HOSTNAME' in os.environ 返回false。事实上,在部署时没有环境属性可用。所有这些属性在部署后都可用。

运行 /opt/elasticbeanstalk/bin/get-config environment 会返回以下内容:

{"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文件:

# [...]

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'],
        }
    }

# [...]

我是否必须进行任何更改才能使这些属性在部署时可用?

【问题讨论】:

  • 我们的环境变量也遇到了同样的问题。在与 AWS 支持人员交谈后,他们告诉我们环境变量中的特殊字符破坏了变量的部署脚本并导致了问题。我们通过删除/更改具有特殊字符的变量来解决它。这是一个特别难以找到的问题,因为它不会在 EB 日志中引发错误......花了很长时间进行分类并得到解决。
  • 旁注,特别是我认为它是一个未转义的,它会导致部署脚本停止在实例上设置变量。该变量将在 EB 控制台中正确显示,但实际上不会正确部署到环境中。
  • @hephalump; env var 中的特殊字符是指 RDS_DB_NAME 中的 _ 或其值中的任何特殊字符?
  • 没有。我的意思是在实际变量值中,在 EB 中的任何 env var 中。我们的问题是我们在另一个env var’s(即实际变量值中的特殊字符)中有一个反引号,它正在转义env var部署脚本......虽然我们收到了成功的部署通知,但它不是成功。
  • @hephalump;是的。我也收到成功部署消息,并且日志文件中没有错误或警告。

标签: python django database amazon-web-services amazon-elastic-beanstalk


【解决方案1】:

似乎这是一个严重的错误,AWS 并不关心它。我想出几种方法来完成这项工作,但所有这些方法都需要登录 EB 环境并进行一些手动工作。

解决方案 1

正如hephalump评论中所建议的那样

  1. 创建 AWS 密钥管理器

  2. 在EB的环境Configuration->Security->Edit中检查IAM instance profile

  3. 然后转到 IAM 用户控制台并转到 Roles。从那里您可以将策略附加到秘密管理器的实例配置文件。

  4. 完成后,部署项目

  5. 然后登录环境(eb ssh environment_name)。

  6. 转到/var/app/current/ 目录并运行以下命令:source /var/app/venv/*/bin/activate

  7. 最后运行python3 manage.py migrate

解决方案 2

  1. 编辑.bash_profile并在文件末尾添加export这些变量:

     export RDS_DB_NAME=your_dbname
     export RDS_USERNAME=user
     export RDS_PASSWORD=pass
     export RDS_HOSTNAME=host_endpoint
     export RDS_PORT=3306
    
  2. 运行source ~/.bash_profile

  3. 现在您可以部署您的项目了。

解决方案 3

  1. 在 EB 环境的配置中设置所有环境属性。 (转到Configuration->Software->Edit->Environment properties 并添加键和值)。

2。在settings.py开头添加这个sn-p

    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)
  1. 转到数据库部分并用这个 sn-p 替换它

     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'],
         }
     }
    
  2. 部署项目。

  3. 登录环境 (eb ssh environment_name)。

  4. 转到/var/app/current/ 目录并运行以下命令:source /var/app/venv/*/bin/activate

  5. 最后运行python3 manage.py migrate

结论:

解决方案 1 有点复杂,秘密管理器不是免费的(仅限 30 天试用)。
解决方案 2 最简单的一种,但我不建议在 EB 上手动调整任何文件。
解决方案 3 是一种我将使用的清洁解决方案。此解决方案还会在将来修复此错误。

【讨论】:

  • 为什么要使用activate?只需使用 manage.py 的路径和命令运行 venv python 解释器:/var/app/venv/*/bin/python /var/app/current/manage.py migrate.
  • 激活虚拟环境
  • 你不需要。激活只不过是PATH 修改以选择正确的解释器以供交互式使用。
  • 当唯一重要的代码是 PATH=/path/to/venv/bin:$PATH 时,我一直不明白为什么他们让它听起来和看起来如此神奇。 subshel​​l、PROMPT mangling 等都是为了增强交互使用,但它也使“激活虚拟环境”听起来像是完成任何事情的强制性过程。
  • @Melvyn 是的,你是对的。这可以在不激活虚拟环境的情况下完成,但激活它然后执行工作是另一种方式,但肯定不是强制性的。
【解决方案2】:

在系统中使用环境属性,例如。运行 Symfony 命令(使用 envs)你可以简单地运行这个:

/opt/elasticbeanstalk/bin/get-config environment | jq -r "to_entries|map(\"export \(.key)='\(.value|tostring)'\")|.[]" >> /home/ec2-user/.bash_profile 

它将在 .bash_profile 中添加所有道具,因此当您通过 SSH 登录时,它们将全部设置好。当然,最好在 .ebextensions/*.config 的 commands: section 下添加它。

【讨论】:

    猜你喜欢
    • 2015-10-17
    • 2020-11-03
    • 2015-11-19
    • 2020-09-29
    • 2021-12-05
    • 1970-01-01
    • 2014-09-28
    • 2017-08-14
    • 2017-11-15
    相关资源
    最近更新 更多