Puppet Development Tools

好一陣子沒寫 Puppet, 最近回來研究發現多了不少好用的工具,可以有效加速開發速度。

Vagrant

現在 Vagrant provisioner 直接提供了 Puppet 選項,可以幫你 sync hiera, manifests, modules 進去直接 run,也可以帶入 custom options 或是 facter,在開發 modules 的時候可以不用管其他東西,專心 focus 在 pp 本身。

只要在 Vagrantfile 裡面加入這樣的設定即可:

1
2
3
4
5
6
7
8
9
10
  # Puppet config
  config.vm.provider "virtualbox" do |vb, override|
    override.vm.provision "puppet" do |puppet|
      puppet.options = "--parser future --verbose --debug" # For debug only
      puppet.manifests_path = "manifests"
      puppet.manifest_file  = "vagrant.pp"
      puppet.module_path    = "modules"
      puppet.hiera_config_path = "hiera.yaml"
    end
  end

不過有兩個小地方需要注意:

Puppet 版本

Vagrant 附的 Puppet 版本比較舊,是 2.7x。如果有新版本的需求,可以使用這隻 script 來升級 Puppet:

1
2
  # Upgrade Puppet from 2.7 to 3.x
  config.vm.provision :shell, :path => "scripts/upgrade_puppet.sh"

Hiera 目錄

通常 hiera 不會只有一隻檔案,但 Vagrant 只會幫你掛上 modules 和 manifests 資料夾。這時就需要把 hiera 的目錄丟到 manifests 下面,並且在 hiera 設定 :datadir: "%{settings::manifestdir}/hieradata" 直接去吃 manifests 的路徑即可。


Librarian-Puppet

Librarian-Puppet 是一個管理 puppet modules 的工具,基本上跟 bundler 的概念一樣。編寫 Puppetfile 以後,使用指令 librarian-puppet install 來安裝到 modules 目錄下。這樣就不用處理 puppet module install 和指定版本,以及安裝自己 private modules 的問題了。反正使用 librarian-puppet 他會幫你管好一個 modules 目錄。

Puppetfile 支援幾種指定方式,都非常實用:

1
modulefile

只要直接下 modulefile 他就會去吃你 modulefile 裡面的 dependencies。這在開發 puppet modules 的時候會用到。

1
mod "puppetlabs/stdlib"

指定 puppet forge 的 package name。

1
2
3
mod "puppetlabs/apt",
  :git => "git://github.com/puppetlabs/puppetlabs-apt.git",
  :ref => '0.0.3'

指定某 repo 的 ref。

1
2
3
mod "puppetlabs/apt",
  :git => "git://github.com/fake/puppet-modules.git",
  :path => "modules/apt"

指定 repo 下的 path。

1
mod "puppetlabs/apt", :path => "modules/apt"

指定 local path,可以用在 private modules。


Puppet Skeleton

以上這兩個工具搭配起來,開發 Puppet 就變得很容易了:把需要的 community modules 定義在 Puppetfile 裡面,private modules 放在 local, 一樣用 Puppetfile 掛起來安裝,再透過 Vagrant 指定 manifest path, file, hiera 的設定,直接 $ vagrant up 就可以反覆測試 puppet 了。

我有做了一個 puppet-skeleton 的專案,這是我自己開發 Puppet 的專案架構跟 workspace。

Rake Tasks

這邊是一些我自己開發常用的 rake tasks,基本上就是省 keystroke…

1
2
3
4
5
6
7
8
9
10
11
$ rake -T                                  # List all tasks.
$ rake -D                                  # List all tasks with descriptions.
$ rake module:lint                         # Puppet lint.
$ rake module:reinstall                    # Clean and reinstall modules.
$ rake module:sync                         # Sync private modules.
$ rake syntax                              # Syntax check Puppet manifests and templates
$ rake syntax:hiera                        # Syntax check Hiera config files
$ rake syntax:manifests                    # Syntax check Puppet manifests
$ rake syntax:templates                    # Syntax check Puppet templates
$ rake vagrant:provision[name,provisioner] # Provision vagrant VM.
$ rake vagrant:rebuild[name]               # Rebuild vagrant VM.

目錄架構

跟上面講的差不多,除了特別把 roleprofile 兩個 modules 從 private modules 裡面抽出來到頂層。

關於 role 以及 profile 可以看我之前的文章 Roles and Profiles Pattern in Puppet

也算是提供一個這個 pattern 的範例。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
.
├── Gemfile             # Required rubygems, use bundler to install.
├── Puppetfile          # Required puppet modules, use librarian-puppet to install.
├── README.md
├── Rakefile            # Some predefined tasks, to speed up development.
├── Vagrantfile         # Vagrant configuration.
├── hiera.yaml          # Puppet hiera config, only define hierarchy and datadir in this file.
├── docs                # Some documents
├── manifests
│   ├── hieradata         # The actual heirdata stored in this folder.
│   ├── site.pp           # Node definition for production.
│   └── vagrant.pp        # Node definition for local development.
├── private             # Private modules, will be sync into `modules` folder by `librarian-puppet`.
│   ├── common
│   └── users
├── profile             # Profile, abstraction of "Technology stack"
│   ├── files
│   └── manifests
├── role                # Role, abstraction of "What does this server do?"
│   └── manifests
├── spec                # Put test files
└── scripts
    └── upgrade_puppet.sh # Script of upgrading puppet to version 3 on Ubuntu

在 EC2 上測試

只要稍微設定一下 Vagrantfile,就可以利用 Vagrant-AWS 直接 deploy 到 AWS EC2 上面測試。

Comments