适用于多个应用程序的多个环境的 Puppet 架构

Puppet architecture for multiple environments of multiple applications

我的团队使用 Puppet 架构,目前在多个环境(流浪者、暂存、生产)中容纳单个应用程序。

我们现在想要扩展此设置的范围以支持其他应用程序。他们中的许多人将使用我们已经定义的现有模块的子集,而其他人将要求定义新模块(可能共享也可能不共享。)

什么是最合适的 Puppet 架构,以支持多个应用程序的多个环境?

在这样的架构中,每个应用程序大概相当于一个模块。在作为应用程序的模块和作为一个或多个模块的依赖项的模块之间(文件)在结构上进行区分的最佳方式是什么?

是否可以像在顶级 applications 文件夹下添加第三个 modules 文件夹一样简单?还是有更好的分层策略?

到目前为止,研究还没有发现任何最佳实践示例/样板,例如通过 GitHub.

上的 example42 或 puppetlabs

我们的文件结构:

puppet
├── environments
│   ├── production → manifests → init.pp
│   ├── staging → manifests → init.pp
│   └── vagrant → manifests → init.pp
├── hiera.yaml
├── hieradata
│   ├── accounts.yaml
│   ├── common.yaml
│   └── environments
│       ├── production.yaml
│       ├── staging.yaml
│       └── vagrant.yaml
├── modules
│   ├── acl [..]
│   ├── newrelic [..]
│   ├── nginx [..]
│   └── puma [..]
└── vendor
    ├── Puppetfile
    ├── Puppetfile.lock
    └── modules [..]

我相信对于 'most appropriate' 的解决方案有很多意见,但我会告诉你我的意见。

Puppet 实际上是为支持多个环境中的多个应用程序而设计的,但有一些值得注意的注意事项:

  • 所有公共依赖项(在单个环境中)必须固定到同一版本
    • 所以如果你有三个应用程序需要 Apache,你只能有一个 Apache 模块
  • 所有应用程序都可以使用独特的名称来引用
    • I.E.如果您有三个不同的 node.js 应用程序需要它们自己的模块,则您需要为它们提供三个唯一命名的模块(或清单)
  • 您愿意解决 upkeep/maintenance 同时更新多个应用程序的依赖项
    • 如果应用 1 需要更新 Apache 模块依赖项,您愿意确保应用 2-* 保持兼容

要记住的另一件事是 Puppet 的 'environment' 术语是 acknowledged misnomer. Most well operated environments I have seen actually have distinct Puppet masters in each of their true 'environments' (vagrant/dev/stage/prod) in order to avoid the perils of environment leakage 以及测试 Puppet 基础设施的升级(你应该有地方来测试升级到你的不会立即影响您的制作的 Puppet 版本)

因此,这解放了 Puppet 'environment directories' 以摆脱真正的 'environment' 概念,应该被视为 'a collection of modules at a particular revision' 而不是 'environment'。您仍然需要意识到环境泄漏,但这确实为拆分模块开辟了一条潜在途径。

您需要记住的另一个概念是角色和配置文件(Gary Larizza, Adrien Thebo, and Craig Dunn 讨论得很好)。这些有助于将业务逻辑与技术管理模块分开。然后,您可以处理与 code/modules 分开的依赖项排序和面向业务的逻辑,以管理各个组件。

有了所有这些概念,这里有两个架构布局可能非常适合您的用例:

应用环境

puppet
├── environments (Managed by r10k/code manager)
│   ├── app1 
│   │   └── modules 
│   │       ├── profiles [..] 
│   │       └── app1_specific_component [..] 
│   ├── app2
│   │   └── modules 
│   │       ├── profiles [..] 
│   │       └── app2_specific_component [..] 
│   └── app3 
│       └── modules
│           ├── profiles [..] 
│           └── app3_specific_component [..] 
├── hiera.yaml
├── hieradata
│   ├── accounts.yaml
│   ├── common.yaml
│   └── applications
│       ├── app1
│       │   ├── default.yaml
│       │   └── environments (server environments)
│       │       ├── vagrant
│       │       │   └── roles 
│       │       │       ├── role1.yaml
│       │       │       ├── role2.yaml
│       │       │       └── role3.yaml 
│       │       ├── stg
│       │       │   └── roles 
│       │       │       ├── role1.yaml
│       │       │       ├── role2.yaml
│       │       │       └── role3.yaml 
│       │       └── prd
│       │           └── roles 
│       │               ├── role1.yaml
│       │               ├── role2.yaml
│       │               └── role3.yaml
│       ├── app2
│       │   ├── default.yaml
│       │   └── environments 
│       │       ├── vagrant
│       │       │   └── roles 
│       │       │       ├── role1.yaml
│       │       │       ├── role2.yaml
│       │       │       └── role3.yaml 
│       │       ├── stg
│       │       │   └── roles 
│       │       │       ├── role1.yaml
│       │       │       ├── role2.yaml
│       │       │       └── role3.yaml 
│       │       └── prd
│       │           └── roles 
│       │               ├── role1.yaml
│       │               ├── role2.yaml
│       │               └── role3.yaml
│       └── app3
│           ├── default.yaml
│           └── environments 
│               ├── vagrant
│               │   └── roles 
│               │       ├── role1.yaml
│               │       ├── role2.yaml
│               │       └── role3.yaml 
│               ├── stg
│               │   └── roles 
│               │       ├── role1.yaml
│               │       ├── role2.yaml
│               │       └── role3.yaml 
│               └── prd
│                   └── roles 
│                       ├── role1.yaml
│                       ├── role2.yaml
│                       └── role3.yaml 
├── modules (These are common to all environments, to prevent leakage)
│   ├── acl [..]
│   ├── newrelic [..]
│   ├── nginx [..]
│   └── puma [..]
└── vendor
    ├── Puppetfile
    ├── Puppetfile.lock
    └── modules [..]

作为 'release' 的环境(随着时间的推移对 Puppet 代码进行迭代)

puppet
├── environments (Managed by r10k/code manager)
│   ├── release_1 
│   │   └── modules 
│   │       ├── profiles [..] 
│   │       ├── app1_specific_component [..] 
│   │       ├── app2_specific_component [..]
│   │       ├── app2_specific_component [..]
│   │       ├── acl [..] (v1)
│   │       ├── newrelic [..] 
│   │       ├── nginx [..] 
│   │       └── puma [..] 
│   ├── release_2
│   │   └── modules 
│   │       ├── profiles [..] 
│   │       ├── app1_specific_component [..] 
│   │       ├── app2_specific_component [..]
│   │       ├── app2_specific_component [..]
│   │       ├── acl [..] (v1.1)
│   │       ├── newrelic [..] 
│   │       ├── nginx [..] 
│   │       ├── puma [..] 
│   │       └── some_new_thing_for_release_2 [..]
│   └── release_3
│       └── modules 
│           ├── profiles [..] 
│           ├── app1_specific_component [..] 
│           ├── app2_specific_component [..]
│           ├── app2_specific_component [..]
│           ├── acl [..] (v2.0)
│           ├── newrelic [..] 
│           ├── nginx [..] 
│           ├── puma [..] 
│           ├── some_new_thing_for_release_2 [..]
│           └── some_new_thing_for_release_3 [..]
├── hiera.yaml
├── hieradata
│   ├── accounts.yaml
│   ├── common.yaml
│   ├── environments
│   │   ├── release_1.yaml
│   │   ├── release_2.yaml
│   │   └── release_3.yaml
│   └── roles
│       ├── role1
│       │   ├── default.yaml 
│       │   ├── environments (server environments) 
│       │   │   ├── vagrant
│       │   │   │   ├── defaults.yaml
│       │   │   │   └── release (optional, only if absolutely necessary) 
│       │   │   │       ├── release_1.yaml
│       │   │   │       ├── release_2.yaml
│       │   │   │       └── release_3.yaml 
│       │   │   ├── stg
│       │   │   │   ├── defaults.yaml
│       │   │   │   └── release (optional) 
│       │   │   │       ├── release_1.yaml
│       │   │   │       ├── release_2.yaml
│       │   │   │       └── release_3.yaml 
│       │   │   └── prd
│       │   │       ├── defaults.yaml
│       │   │       └── release (optional) 
│       │   │           ├── release_1.yaml
│       │   │           ├── release_2.yaml
│       │   │           └── release_3.yaml 
│       ├── role2
│       │   ├── default.yaml 
│       │   └── environments 
│       │       ├── vagrant
│       │       │   └── defaults.yaml
│       │       ├── stg
│       │       │   └── defaults.yaml
│       │       └── prd
│       │           └── defaults.yaml
│       └── role3
│           └── default.yaml 
├── modules (Anything with ruby libraries should go here to prevent leakage)
│   ├── stdlib [..]
└── vendor
    ├── Puppetfile
    ├── Puppetfile.lock
    └── modules [..]

请记住,嵌套顺序(release/environment/role 等...)是灵活的,具体取决于对您的实施最有意义的顺序(如果您不打算使用它们,则可以取消某些顺序) ).

我鼓励您仅将此信息作为起点,而不是具体的 'do this for instant success'。与您可能在网上(包括我的)找到的假设和 'cookie cutter' 类型的解决方案相比,拥有高技能的 Puppet Architect 与您合作以了解您的确切需求和环境最终会得到一个更好的调整和适当的解决方案。 =14=]