Bootstrapping With Puppet
Version 1 (Nick Fagerlund, 01/05/2012 04:54 pm)
| 1 | 1 | Nick Fagerlund | Bootstrapping With Puppet |
|---|---|---|---|
| 2 | 1 | Nick Fagerlund | ========================= |
| 3 | 1 | Nick Fagerlund | |
| 4 | 1 | Nick Fagerlund | A functional example based around partial automatic installation |
| 5 | 1 | Nick Fagerlund | and upgrading puppet to a functional version, primarily for Ubuntu |
| 6 | 1 | Nick Fagerlund | but possibly adaptable to other Debian-based distributions. |
| 7 | 1 | Nick Fagerlund | |
| 8 | 1 | Nick Fagerlund | ## Requirements |
| 9 | 1 | Nick Fagerlund | |
| 10 | 1 | Nick Fagerlund | - A local apt repository |
| 11 | 1 | Nick Fagerlund | - I use the reprepro package to manage my repository |
| 12 | 1 | Nick Fagerlund | - A quick google found this tutorial |
| 13 | 1 | Nick Fagerlund | [[http://ianlawrence.info/random-stuff/setting-up-a-personal-debian-repository](http://ianlawrence.info/random-stuff/setting-up-a-personal-debian-repository)] |
| 14 | 1 | Nick Fagerlund | - Backported packages for $lsbdistrelease, available in said |
| 15 | 1 | Nick Fagerlund | repository. |
| 16 | 1 | Nick Fagerlund | - Ubuntu has a package called prevu for automating the |
| 17 | 1 | Nick Fagerlund | backporting process, take a look at |
| 18 | 1 | Nick Fagerlund | [[https://wiki.ubuntu.com/Prevu](https://wiki.ubuntu.com/Prevu)] |
| 19 | 1 | Nick Fagerlund | - A trusted.gpg file containing the necessary GPG public keys for |
| 20 | 1 | Nick Fagerlund | said repository, so that apt doesn't complain |
| 21 | 1 | Nick Fagerlund | - A sources.list file containing said repository |
| 22 | 1 | Nick Fagerlund | - The upgradepuppet class below (or similar, adapt as necessary) |
| 23 | 1 | Nick Fagerlund | |
| 24 | 1 | Nick Fagerlund | ## Usage |
| 25 | 1 | Nick Fagerlund | |
| 26 | 1 | Nick Fagerlund | - Define a node in Puppet for your to-be-bootstrapped machine |
| 27 | 1 | Nick Fagerlund | - Install your Ubuntu machine as per usual, with a preseed or |
| 28 | 1 | Nick Fagerlund | without |
| 29 | 1 | Nick Fagerlund | - Install Puppet from the official repositories (it'll be old, |
| 30 | 1 | Nick Fagerlund | 0.22.something) |
| 31 | 1 | Nick Fagerlund | - Note: These last two steps can be replaced if you can work out |
| 32 | 1 | Nick Fagerlund | how to make a preseed disk with 0.22 installed already, although, |
| 33 | 1 | Nick Fagerlund | why you'd put 0.22 on your disk instead of 0.24.1 beats me..) |
| 34 | 1 | Nick Fagerlund | - Personally here I stop the puppetd daemon (apt-get install |
| 35 | 1 | Nick Fagerlund | puppet && /etc/init.d/puppet stop) and run puppetd --test |
| 36 | 1 | Nick Fagerlund | - Magical things will happen! Packages will be upgraded, Puppet |
| 37 | 1 | Nick Fagerlund | will be started, then stopped and disabled. |
| 38 | 1 | Nick Fagerlund | - Using a case statement in your node (see below) normal |
| 39 | 1 | Nick Fagerlund | operations will continue. |
| 40 | 1 | Nick Fagerlund | |
| 41 | 1 | Nick Fagerlund | ### upgradepuppet class |
| 42 | 1 | Nick Fagerlund | |
| 43 | 1 | Nick Fagerlund | This is the upgradepuppet class: |
| 44 | 1 | Nick Fagerlund | |
| 45 | 1 | Nick Fagerlund | class upgradepuppet { |
| 46 | 1 | Nick Fagerlund | file { "/etc/apt/sources.list": |
| 47 | 1 | Nick Fagerlund | source => "puppet://puppet/files/sources.list.${lsbdistcodename}", |
| 48 | 1 | Nick Fagerlund | ensure => present; |
| 49 | 1 | Nick Fagerlund | "/etc/apt/trusted.gpg": |
| 50 | 1 | Nick Fagerlund | source => "puppet://puppet/files/trusted.gpg", |
| 51 | 1 | Nick Fagerlund | ensure => present; |
| 52 | 1 | Nick Fagerlund | "/etc/puppet/puppetd.conf": |
| 53 | 1 | Nick Fagerlund | ensure => absent, |
| 54 | 1 | Nick Fagerlund | require => [ Package[puppet], Package[facter] ]; |
| 55 | 1 | Nick Fagerlund | } |
| 56 | 1 | Nick Fagerlund | |
| 57 | 1 | Nick Fagerlund | exec { "/usr/bin/apt-get update": |
| 58 | 1 | Nick Fagerlund | alias => "aptgetupdate", |
| 59 | 1 | Nick Fagerlund | require => [ File["/etc/apt/sources.list"], File["/etc/apt/trusted.gpg"] ], |
| 60 | 1 | Nick Fagerlund | subscribe => [ File["/etc/apt/sources.list"], File["/etc/apt/trusted.gpg"] ], |
| 61 | 1 | Nick Fagerlund | refreshonly => true; |
| 62 | 1 | Nick Fagerlund | } |
| 63 | 1 | Nick Fagerlund | |
| 64 | 1 | Nick Fagerlund | package { "puppet": |
| 65 | 1 | Nick Fagerlund | ensure => latest, |
| 66 | 1 | Nick Fagerlund | require => Exec["aptgetupdate"]; |
| 67 | 1 | Nick Fagerlund | "facter": |
| 68 | 1 | Nick Fagerlund | ensure => latest, |
| 69 | 1 | Nick Fagerlund | require => Exec["aptgetupdate"]; |
| 70 | 1 | Nick Fagerlund | } |
| 71 | 1 | Nick Fagerlund | |
| 72 | 1 | Nick Fagerlund | service { "puppet": |
| 73 | 1 | Nick Fagerlund | enable => false, |
| 74 | 1 | Nick Fagerlund | require => Package[puppet]; |
| 75 | 1 | Nick Fagerlund | } |
| 76 | 1 | Nick Fagerlund | } |
| 77 | 1 | Nick Fagerlund | |
| 78 | 1 | Nick Fagerlund | ### Example Node |
| 79 | 1 | Nick Fagerlund | |
| 80 | 1 | Nick Fagerlund | This is an example of a node: |
| 81 | 1 | Nick Fagerlund | |
| 82 | 1 | Nick Fagerlund | node proxy { |
| 83 | 1 | Nick Fagerlund | case $puppetversion { |
| 84 | 1 | Nick Fagerlund | "0.24.1": { |
| 85 | 1 | Nick Fagerlund | $munin_group = "infrastructure" |
| 86 | 1 | Nick Fagerlund | $apache2_port = "80" |
| 87 | 1 | Nick Fagerlund | $apache2_ssl = "enabled" |
| 88 | 1 | Nick Fagerlund | include generic-systems |
| 89 | 1 | Nick Fagerlund | include firewall-ftp |
| 90 | 1 | Nick Fagerlund | include users |
| 91 | 1 | Nick Fagerlund | include util |
| 92 | 1 | Nick Fagerlund | include monitoring |
| 93 | 1 | Nick Fagerlund | include squidproxy |
| 94 | 1 | Nick Fagerlund | include apache2::no_default_site |
| 95 | 1 | Nick Fagerlund | include git::daemon |
| 96 | 1 | Nick Fagerlund | |
| 97 | 1 | Nick Fagerlund | apache2::site { "repository": |
| 98 | 1 | Nick Fagerlund | ensure => present, |
| 99 | 1 | Nick Fagerlund | source => "puppet:///apache/maxrepo"; |
| 100 | 1 | Nick Fagerlund | } |
| 101 | 1 | Nick Fagerlund | |
| 102 | 1 | Nick Fagerlund | munin::plugin { [ squid_cache, squid_requests, squid_traffic ]: |
| 103 | 1 | Nick Fagerlund | config => "user root\nenv.squidport 8080" |
| 104 | 1 | Nick Fagerlund | } |
| 105 | 1 | Nick Fagerlund | } |
| 106 | 1 | Nick Fagerlund | |
| 107 | 1 | Nick Fagerlund | default: { |
| 108 | 1 | Nick Fagerlund | include upgradepuppet |
| 109 | 1 | Nick Fagerlund | } |
| 110 | 1 | Nick Fagerlund | } |
| 111 | 1 | Nick Fagerlund | } |
| 112 | 1 | Nick Fagerlund | |
| 113 | 1 | Nick Fagerlund | # Bootstrapping RHEL/Centos and Puppet |
| 114 | 1 | Nick Fagerlund | |
| 115 | 1 | Nick Fagerlund | ## Building the system |
| 116 | 1 | Nick Fagerlund | |
| 117 | 1 | Nick Fagerlund | To begin with we need to build the system. For this, unless you |
| 118 | 1 | Nick Fagerlund | already have something in place, look at using Cobbler |
| 119 | 1 | Nick Fagerlund | [[http://cobbler.et.redhat.com/](http://cobbler.et.redhat.com/)]. |
| 120 | 1 | Nick Fagerlund | This handles the tftp/dhcp/kickstart part of building a RHEL/Centos |
| 121 | 1 | Nick Fagerlund | system. Once you have installed this and set it up, you'll need to |
| 122 | 1 | Nick Fagerlund | change it to use dnsmasq. This is so that you can provide |
| 123 | 1 | Nick Fagerlund | --hostname=systemname to cobbler when adding systems, and have DHCP |
| 124 | 1 | Nick Fagerlund | serve up this information to the host. |
| 125 | 1 | Nick Fagerlund | |
| 126 | 1 | Nick Fagerlund | I also recommend adding EPEL to your cobbler configuration, via |
| 127 | 1 | Nick Fagerlund | something like: |
| 128 | 1 | Nick Fagerlund | |
| 129 | 1 | Nick Fagerlund | cobbler repo add --name=EPEL-x86_64 --mirror=http://download.fedora.redhat.com/pub/epel/5/x86_64 |
| 130 | 1 | Nick Fagerlund | |
| 131 | 1 | Nick Fagerlund | This will download ALL of EPEL locally. If you want you can add |
| 132 | 1 | Nick Fagerlund | --mirror-locally=0 to this line, which will direct kickstart to |
| 133 | 1 | Nick Fagerlund | download files directly from EPEL. For this to work, the addresses |
| 134 | 1 | Nick Fagerlund | you serve via DHCP must have full internet access. |
| 135 | 1 | Nick Fagerlund | |
| 136 | 1 | Nick Fagerlund | Next, edit the kickstart file you use to include something like: |
| 137 | 1 | Nick Fagerlund | |
| 138 | 1 | Nick Fagerlund | %packages |
| 139 | 1 | Nick Fagerlund | @base |
| 140 | 1 | Nick Fagerlund | ruby |
| 141 | 1 | Nick Fagerlund | ruby-libs |
| 142 | 1 | Nick Fagerlund | puppet |
| 143 | 1 | Nick Fagerlund | facter |
| 144 | 1 | Nick Fagerlund | ruby-shadow |
| 145 | 1 | Nick Fagerlund | rubygems |
| 146 | 1 | Nick Fagerlund | |
| 147 | 1 | Nick Fagerlund | %post --nochroot |
| 148 | 1 | Nick Fagerlund | # Copy netinfo, which has our FQDN from DHCP, into the chroot |
| 149 | 1 | Nick Fagerlund | test -f /tmp/netinfo && cp /tmp/netinfo /mnt/sysimage/tmp/ |
| 150 | 1 | Nick Fagerlund | |
| 151 | 1 | Nick Fagerlund | ## |
| 152 | 1 | Nick Fagerlund | ## Workflow: Turn on puppet for next boot, set hosts and resolv.conf, then |
| 153 | 1 | Nick Fagerlund | ## figure out the hostname. Write a new /etc/sysconfig/network file to keep |
| 154 | 1 | Nick Fagerlund | ## the hostname, then set the hostname and run puppet to get the certificate. |
| 155 | 1 | Nick Fagerlund | ## Sign it on the other side during first boot. |
| 156 | 1 | Nick Fagerlund | |
| 157 | 1 | Nick Fagerlund | %post |
| 158 | 1 | Nick Fagerlund | /sbin/chkconfig --level 345 puppet on |
| 159 | 1 | Nick Fagerlund | /bin/echo "$PUPPETIP puppet" >> /etc/hosts |
| 160 | 1 | Nick Fagerlund | /bin/echo "nameserver $NAMESERVERIP" >> /etc/resolv.conf |
| 161 | 1 | Nick Fagerlund | hostname $hostname |
| 162 | 1 | Nick Fagerlund | # Write out the hostname to a file for reboot. |
| 163 | 1 | Nick Fagerlund | /bin/echo -e "NETWORKING=yes\nHOSTNAME=$hostname" > /etc/sysconfig/network |
| 164 | 1 | Nick Fagerlund | /usr/sbin/puppetd -tv |
| 165 | 1 | Nick Fagerlund | |
| 166 | 1 | Nick Fagerlund | /usr/sbin/rhnreg_ks --profile="$hostname" --username="" --password="" |
| 167 | 1 | Nick Fagerlund | $yum_config_stanza |
| 168 | 1 | Nick Fagerlund | $kickstart_done |
| 169 | 1 | Nick Fagerlund | |
| 170 | 1 | Nick Fagerlund | You need to replace $PUPPETIP with the host name or IP address of |
| 171 | 1 | Nick Fagerlund | the Puppet server, and $NAMESERVERIP with a working nameserver from |
| 172 | 1 | Nick Fagerlund | whatever DHCP range you set up as part of cobbler. This bit is only |
| 173 | 1 | Nick Fagerlund | required if you use RHEL, and want to automate the RHN |
| 174 | 1 | Nick Fagerlund | registration, or if you turned on --mirror-locally=0 when adding |
| 175 | 1 | Nick Fagerlund | EPEL. Otherwise skip the resolv.conf and rhnreg section. |
| 176 | 1 | Nick Fagerlund | |
| 177 | 1 | Nick Fagerlund | This will run puppetd against the puppet master while still |
| 178 | 1 | Nick Fagerlund | kickstarting. You then need to sign the certificate, so that it can |
| 179 | 1 | Nick Fagerlund | run Puppet during the initial boot. |