【问题标题】:How to manage credentials with a multi-stages, single-environment Rails app?如何使用多阶段、单一环境的 Rails 应用程序管理凭据?
【发布时间】:2020-10-10 19:33:15
【问题描述】:

TL;博士

如何在两个生产和暂存的 Rails 应用程序中使用production.yml.encstaging.yml.enc 凭据文件,而该应用程序只有常规的developmenttestproduction 环境?

我正在使用 Heroku,并在这个问题中引用它。然而,这并不特定于该供应商。

详细说明

一个应用程序经常部署多次。一个实例用作生产,而另一个是暂存应用程序,预计将投入生产。 Rails 促进了这种模式,因为创建新环境很容易。

但是,Heroku suggests not to do this,有充分的理由。例如,人们可能会想在这里和那里放一些if Rails.env.production?,为一些“但它在登台工作!?”铺平道路。周五晚上。最好有一个单一的生产环境,使用不同的参数集来实际区分各个阶段(例如,不同的 AWS S3 存储桶名称、不同的 API 密钥等)。为此,Heroku 的建议是依赖环境变量。

自 Rails 5.2 及更高版本的 Rails 6 以来,凭据可通过 config/credentials 中的加密 Yaml 文件方便地处理。这通常是人们希望存储从一个环境更改为另一个环境的所有这些变量的地方,而不是使用混乱的环境变量。这种机制可以在 Heroku 中使用,这要归功于一个包含用于解密凭证文件的密钥的 RAILS_MASTER_KEY 环境变量。

但这些部分不太合身。我们如何才能拥有一个 production 环境,而凭据文件是每个环境的?

【问题讨论】:

  • 关于这个问题的一些背景信息。我发现 Heroku 的建议不要复制环境,这在 Figaro gem 中已经很容易做到了。但我想使用 Rails 内置的凭证机制。所以我搜索了一些现有的解决方法,但找不到任何解决方法。我特别期待 Heroku 的一些东西,他的文档总体上非常出色。我自己的答案对我来说很好,但我想知道是否有更好的解决方案。

标签: ruby-on-rails heroku


【解决方案1】:

这可以通过暂存凭证文件和密钥以及基于环境变量的application.rb 中的开关来实现:

  • 使用EDITOR=vi rails credentials:edit --environment staging 创建和填充暂存凭证文件和密钥。

  • application.rb,添加:

    # Introduce the environment variable RAILS_CREDENTIALS_ENVIRONMENT to specify a custom
    # environment name of which to use the credentials file. Specifically aimed to use in staging,
    # where the environment is set to "production", but we need to use the "staging" environment variables.
    # This environment variable is also used to select the corresponding key file or -if that does not exist-
    # the corresponding environment variable.
    if ENV['RAILS_CREDENTIALS_ENVIRONMENT'].present?
      new_filename_no_ext = Rails.root.join 'config', 'credentials', ENV['RAILS_CREDENTIALS_ENVIRONMENT']
      config.credentials.content_path = "#{new_filename_no_ext}.yml.enc"
    
      if File.exist? "#{new_filename_no_ext}.key"
        config.credentials.key_path = "#{new_filename_no_ext}.key"
      end
    end
    
  • 根据具体情况,将环境变量RAILS_CREDENTIALS_ENVIRONMENT 设置为productionstaging。例如,Heroku 这样做:

    heroku config:set -a theapp-staging RAILS_CREDENTIALS_ENVIRONMENT=staging
    
  • 如果在暂存或生产中您想将密钥存储在环境变量而不是密钥文件中,则只需将密钥分配给 RAILS_MASTER_KEY 环境变量。如文件所述,这优先于存储在文件中的密钥。请注意,在您的开发机器上,您不希望设置RAILS_MASTER_KEY,否则所有环境的凭据文件仍然获得相同的密钥,因此需要访问(例如)仅开发凭据的每个人都可以访问.

【讨论】:

    【解决方案2】:

    在您的源代码存储库或本地服务器磁盘中,每个环境都有几个文件,可以工作,但您将有几个带有硬编码值的文件。

    但是,如果您希望多个团队对您的单个应用程序有多个要求,则您将需要多个开发和测试环境,以便让一个独立的团队完全负责他们的服务:

    • 发展
    • 发布/部署
    • Ops(不是平台/系统管理)

    一种管理方法是:在称为配置管理器的平台上外部化您的配置

    这个平台,必须具备以下特点:

    • 应用程序创建键值对。喜欢 heroku 网络仪表板
    • 公开 http 端点以从远程应用程序获取此变量
    • 安全

    如果您的语言支持热重载变量,您的 rails 应用程序必须在启动阶段或即时获取变量。

    这里有一些配置管理器:

    通过这种方法,您将拥有一个平台来管理多个环境的多个应用程序,例如创建 heroku Web 变量,但更复杂。

    【讨论】:

      猜你喜欢
      • 2012-09-03
      • 1970-01-01
      • 1970-01-01
      • 2013-07-05
      • 2019-10-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多