这是关于环境变量/结构的方法和建议的非常广泛的问题。但是最终,我正在针对“如何存储我的环境变量?”这一非常具体的问题寻找答案。

首先要澄清一下:


环境对我而言,可以是3到10台服务器,并且是包含特定客户基础结构的一种方式。
在每个环境中,都有一些变量,这些变量大部分是由一些关键输入(名称,大小等)自动生成的。 br />
现在,我们将所有环境变量存储在这样的结构中:

<playbook>.yml                   # Various playbooks for deployment
roles/windows                    # Ansible role for Ubuntu
roles/ubuntu                     # Ansible role for Ubuntu
config/hosts/<name>.yml          # Ansible inventory
config/hosts/vars/<name>.json    # Environment specific variables 


现在,配置已初始化作为上面git存储库中的子模块。由于变量文件的更改非常频繁,这导致了数据更改的问题,两次提交之间发生了一次,两次甚至三遍,从而使更改越来越难以跟踪。希望以集中/可扩展的方式存储我们所有的客户变量,然后将其与ansible的动态库存挂钩。

我知道有一些技术似乎可以起到一定作用诸如Consul之类的必需项,但它们似乎在服务于一个大型应用程序而不是许多较小的,略有不同的应用程序的环境中效果最佳。

我本质上认为我们必须编写清单脚本,然后再推销所有脚本将我们的数据存储到一些非专用的内置数据库中,然后继续进行,就好像什么都没有改变一样。我认为这可能是一种减少当前存储的大量数据的方式,也许是研究存储数据的不同方式,而不仅仅是扩展再次提供服务的内容。

我希望有人在面对许多较小的环境而不是一个,两个或三个巨大的环境时,具有将基础结构实现为代码的某种经验。

有什么建议吗?

#1 楼

我已经以可扩展的方式运行了两次环境变量,但都没有完美的结果,因为正如我所发现的那样,正确处理是一件非常棘手的事情。我将在下面总结我的两种经验:

公共因素


环境变量与原始源代码存储在单独的存储库中(它们一起调制,但仍基于单独的存储库。
工件和变量是独立的“构建”过程。
环境变量没有单独的释放过程。如果要更改环境变量,则需要经过相同的更改审核委员会和通常的操作。

使用领事KV对

环境变量是从工件库中加载的(永远不要原始git repo)并加载到命名空间的KV对树中,例如

/env/dev1/my/application/v1.1.1

,其中先前的dev1是环境的名称,my / application是应用程序的名称空间,而v1.1.1是要使用的环境变量的版本。对于开发人员来说,所有这些都是不可见的。在运行时,平台会检查环境是否在当前领事群集中存在(如果没有问题且出错了),然后它会检查应用程序名称空间的子树(这样,在一个应用程序中就不会有交叉污染的情况)引用另一个应用变量),然后从连接到可部署工件的标签获取配置的版本号。更新此标签是这里的关键,因为这意味着如果我们丢失了两个生产数据中心,则可以通过简单地从可部署工件中读取元数据并将所有环境变量加载到KV存储中来再次站起来。

这种方法的问题
开发人员总是,而且我每次都想找到一种方法来将配置更改放到对应用程序的运行方式有重大影响的环境中。因为最终使批准配置更改比更改代码更容易获得批准。

存储带有嵌入变量的“部署”工件

这紧密地结合了工件的确切版本到配置的版本。如果更改了配置,则必须重建此部署工件。

部署工件本身实质上是一个yaml文件,其中包含可发布二进制文件的URL以及附加到该文件的所有配置。

该平台包含用于读取变量的组件,然后在启动时将其放入应用程序的进程树中。

到目前为止,由于存在人工制品,我们已经取得了很多成功可以追溯历史,并且我们可以举起任何审查委员会,并说:“这是我们唯一关心的工件,我们不需要查看任何其他更改,只需更改此东西”(即部署应用程序,包括环境变量等。

这使得开发人员尝试在其应用程序中构建逻辑以使其能够基于变量更改其行为,从而使他们可以轻松地进行更改而又不会滑动而变得有点困难经过适当的测试周期。

奖励积分

考虑应用程序的秘密。到目前为止,我们对此的解决方案是提供一个公共RSA密钥,开发团队可以使用它来加密扩展的Java密钥存储库(几乎每种语言在某个地方都有可以读取Java密钥存储库的库),然后将其视为第三种工件并被拉到服务器上,用我们的平台私钥解密,并在运行时提供给应用程序。

秘密管理本身就是蠕虫病毒。但这可能值得考虑。

评论


回复:应用程序的秘密,我建议您看一下Vault(vaultproject.io),因为它也是Hashicorp工具链的一部分,并且与Consul(以及该框中的其他工具)进行了很好的集成。

– Michael Bravo
17年3月14日在22:04

考虑到hashicorp的功能通常如此出色,实际上我对Vault非常不满意。从本质上说,他们的产品与市场上其他产品的三个主要差距-1.“秘密秘密”本质上就是该模型所要解决的问题。我正在分片或使用HSM。但实际上,这只是秘密交易。 2.工具兼容性,与其他工具不同,它不支持插件3.价格。当我告诉公司我认为保管库很昂贵时,我不敢相信。他们拒绝了产品,因为它们太便宜了,结果搞砸了。但是金库如此之大,以至于他们甚至都没有考虑。

– hvindin
17年3月17日在16:05

值得一提的是,如果您使用付费版本,这只会使成本高昂。 Vault的核心产品是开源的。当然,他们没有在他们的网站上列出专业版/企业版的价格,因此我不知道这些版本的价格有多不合理。

–阿德里安
17 Mar 22 '17 at 20:13

嗯,我没有注意到我的评论中有遗漏的地方,尽管为了公平起见,我关于保管库的前两个问题仍然存在。虽然,与其他hashicorp产品相比,这些是我对保险库的想法,但我认为所有这些都很棒。与市场上的其他产品相比,执行类似功能的功能可能相当,只是出于某些原因比预期贵得多。

– hvindin
17 Mar 22 '17 at 20:54

您是否可以举一个“在其应用程序中构建逻辑,该逻辑将根据变量更改其行为,以便他们无需进行适当的测试周期即可更改的内容”的示例?听起来确实很普通,但是我无法想象一个具体的例子。

– kenchew
17 Mar 23 '17 at 16:42

#2 楼

如果您的环境是针对每个客户的,那么我建议您在特定情况下为每个客户建立一个存储库。 (通常是每个环境的存储库。)此存储库将具有标准目录结构,用于环境变量,ansable变量和清单,高度加密的机密(帐户访问令牌,私钥等)。您可以将代码git子模块到那些存储库中。我可能会在多个存储库中执行此操作。一个用于烦人的角色和模块,一个用于维护和部署脚本,一个用于环境中运行的每个主要应用程序。

现在,您可以选择实际地分叉代码或将子模块固定在特定的标签上以进行发布,确保除非经过测试和发布,否则管理客户环境的代码不会更改。

如果您使用工件存储库,请确保对工件进行了正确的版本控制,并在环境变量中指定了这些版本

自动化非常重要,因为环境变量不应由人在可能的情况下更新,而应由脚本生成。确保每个客户库存中几乎没有手动更新,并且开发人员仅更新代码存储库。如果他们想更改配置,则应对生成脚本之一进行更改,然后运行生成脚本来生成变量,并将差异提交到客户存储库中。为此过程需要设置持续集成。在某些情况下,没有此存储库将无法维护。

评论


仅一个反对意见:机密不应该进入版本控制存储库,除非它具有严格的访问控制支持。 Git不会-谁拉存储库的人都可以看到秘密,这可能是一个问题-它们不再是秘密。

–丹·科尼莱斯库(Dan Cornilescu)
17年4月6日在5:22

接得好。它是加密的机密。解密密钥具有欺骗性。

–吉里·克鲁达(Jiri Klouda)
17年4月6日在11:57