Puppet Mode for Emacs
I am planning to write my manifests locally in emacs so I will get puppet mode for emacs.
$ cd ~/elisp/ $ git clone http://github.com/puppetlabs/puppet-syntax-emacs.git Cloning into 'puppet-syntax-emacs'... remote: Counting objects: 63, done. remote: Compressing objects: 100% (46/46), done. remote: Total 63 (delta 20), reused 55 (delta 17) Unpacking objects: 100% (63/63), done. $Add the following to ~/.emacs and evaluate the following S-expressions:
(add-to-list 'load-path "~/elisp/puppet-syntax-emacs") (setq py-install-directory "~/elisp/puppet-syntax-emacs") (require 'puppet-mode)
Set up versioning for a module
At work we use an authoritative (by convention) git depot. I also keep a personal authoritative git depot on a vps on the Internet so I will create a bare repository there but which depot I use is arbitrary.
ssh me.xen.prgmr.com cd /opt/git/ mkdir hosts.git cd hosts.git git init --bare logoutI will then clone this empty repository down into a place on my laptop to work:
$ cd ~/src/puppet/hosts $ git clone me@me.xen.prgmr.com:/opt/git/hosts.git Cloning into 'hosts'... warning: You appear to have cloned an empty repository. $
Write a simple module to manage /etc/hosts
Inside the empty repository that I cloned I will create the module:
$ mkdir -p hosts/{files,templates,manifests} $ touch hosts/manifests/init.pp $ mkdir -p hosts/templates $ touch templates/hosts.erbPut the following in hosts/manifests/init.pp:
class hosts { file { "/etc/hosts": ensure => file, owner => "root", group => "root", mode => 0644, } File['/etc/hosts'] { content => template('hosts/hosts.erb'), } }Put the following in templates/hosts.erb:
127.0.0.1 localhost.localdomian localhost 127.0.0.1 <%= @fqdn %> <%= @hostname %> # continue with other hosts as you see fit
Commit the changes and push them back to the depot:
$ cd ~/src/puppet/hosts $ git add * $ git status # On branch master # # Initial commit # # Changes to be committed: # (use "git rm --cached..." to unstage) # # new file: templates/hosts.erb # new file: manifests/init.pp # $ git commit -m "first version of hosts" [master (root-commit) 524416d] first version of hosts 2 files changed, 23 insertions(+) create mode 100644 hosts/templates/hosts.erb create mode 100644 hosts/manifests/init.pp $ $ git push origin master Counting objects: 8, done. Delta compression using up to 4 threads. Compressing objects: 100% (4/4), done. Writing objects: 100% (8/8), 754 bytes, done. Total 8 (delta 0), reused 0 (delta 0) To me@me.xen.prgmr.com:/opt/git/hosts.git * [new branch] master -> master $
On the Puppet Server
A note about some conventions on my set up. My Puppet server has /etc/puppet/modules but it's a symlink to environments/common and I have used an ACL to give myself access to it so I can radiply make changes without being root (this will come in handy later when we talk about how I speed up the cycle):
[root@puppet puppet]# pwd /etc/puppet [root@puppet puppet]# ls -l modules lrwxrwxrwx. 1 root root 19 Sep 24 02:10 modules -> environments/common [root@puppet puppet]# cd environments [root@puppet environments]# setfacl -m u:me:rwx common/ [root@puppet environments]#
[me@puppet ~]$ cd /etc/puppet/modules/ [me@puppet modules]$ git clone me@me.xen.prgmr.com:/opt/git/hosts.git Initialized empty Git repository in /etc/puppet/environments/common/hosts/.git/ remote: Counting objects: 8, done. remote: Compressing objects: 100% (4/4), done. Receiving objects: 100% (8/8), done. remote: Total 8 (delta 0), reused 0 (delta 0) [me@puppet modules]$
On Foreman
More > Configuration > Puppet Classes
Click "Import from puppet". You should then see the class name "hosts". Select it and then you should see something like the following:
Select the environments you want to import the new module into and then select "Update". Once the module is imported, select the servers you want to have the new module. For example, you can apply the new module to the puppet-agent client.
On a Puppet client
From the puppet-agent server you can test the new configuration and observe the change.
[root@puppet-agent ~]# md5sum /etc/hosts b259bdfd326846029c25beff10fc5ac6 /etc/hosts [root@puppet-agent ~]# puppet agent [root@puppet-agent ~]# puppet agent --test Info: Retrieving plugin Info: Caching catalog for puppet-agent.example.com Info: Applying configuration version '1384016280' Notice: Finished catalog run in 0.29 seconds [root@puppet-agent ~]# md5sum /etc/hosts fd34f5442b4209a472d6ea8ac8e24d77 /etc/hosts [root@puppet-agent ~]#
Speeding up the Cycle
I am used to having a git depot at work so I've shown how to stick one in the middle of the cycle but to do a commit and update for each revision of code is not practical. To get around this I can write code on the puppet VM itself (I am the only user for this environment), but use a local editor on my laptop. I prefer to do this with emacs tramp and have the following to my .emacs:
(setenv "puppet" "/ssh:me@puppet.example.com:/etc/puppet/modules/")
These conventions could be applied when developing puppet modules in a development environment like the one described here and then applied to a production environment. For example, I could write a module in this development puppet environment and check it into the git depot at work as I reached the appropriate points in my development. When ready it could then get checked into the puppet modules directory on a production puppet server but in the staging or QA environment of that puppet server (see Chapter 3 of Pro Puppet) so it could be further tested before getting pushed into production. The assumed goal here is that you would want to develop a puppet module without needing to be tethered to the servers at work.
Update: a previous version of this post had a bug as /etc/host was in files and not a template. This would not work correctly has there would be no reference to the the loopback device relative to the hostname. The need for a variable here means you need a template, not a file.
No comments:
Post a Comment