How to bootstrap puppetmaster on lxc on Ubuntu?
5 March, 2021 by
How to bootstrap puppetmaster on lxc on Ubuntu?
Administrator
| No comments yet

Installation of puppet master on Ubuntu has always been a matter of luck and a lot of patience to me – there are many seemingly unrelated things to do which has to be done in the precise order, many combinations and changing behaviour of the software. So I set to write a bootstrapping script, which one day would be able to automate this task. I share it here in hope, that with help of you it will be a good starting point for many beginners.

Input:

  • Name of the lxc container (puppetmaster)
  • Name of the codebase of ubuntu (i.e. whether it is precise, saucy or trusty) mycodename.
  • Fully qualified domain name for the puppetmaster (puppetmasterfqdn)
  • User used to operate the puppet on the machine; he also is an owner of the /etc/puppet(puppetuser)
  • Location of the external git repository. It will be cloned into the lxc container. gitlocation
  • Location of the public ssh key used for login (puppetauth)
  • Static IP address of the container, preferably inside the lxc’s private network (puppetip)
  • Gateway for the lxc. It could be set automatically based on the default lxc configuration, but I am too lazy to write automation around it (puppetgetewayip)

Features:

  • Installs the lxc container support on the host
  • Installs the ubuntu’s template (the codename can be customized)
  • installs the user’s ssh key on the machine
  • installs puppetmaster with puppetdb support (for stored configs)
  • sets fixed IP address.
  • connects the external puppet git repository with the container

The script is written in a spirit of puppet, i.e. it makes sure that certain properties of the system are set, skipping actions if they are set already. So it can be run as many times, as needed.

As an added bonus it also adjusts the user’s name from the default ‘ubuntu’

 

the script :

 

 

#!/bin/bash

puppetmaster=puppetmaster
puppetmasterfqdn=puppetmaster.fqdn.name
puppetuser=adam
gitlocation=/home/puppet.git
puppetauth=`cat ~/.ssh/id_rsa.pub`
puppetip='10.0.3.90'
puppetgetewayip='10.0.3.1'

#mycodename=`lsb_release -c | perl -pe 's/^Codename:\s*(.*)$/$1/'`
mycodename=saucy

######################################

mydir="/var/lib/lxc/$puppetmaster/rootfs"


#lxc installation

sudo dpkg -s lxc>/dev/null
if [ $? -eq 0 ]; then
    echo "lxc already installed!"
else
    sudo apt-get --yes install lxc
fi


#Container creation

sudo lxc-ls | grep $puppetmaster >/dev/null

if [ $? -eq 0 ]; then
    echo "Container '$puppetmaster' already created!"
else
    sudo lxc-create -t ubuntu -n $puppetmaster -- -r $mycodename
fi


#Container's hostname

sudo grep $puppetmasterfqdn $mydir/etc/hostname >/dev/null
if [ $? -eq 0 ]; then
    echo "Puppet master's name is correctly set to FQDN!"
else
    echo $puppetmasterfqdn | sudo tee $mydir/etc/hostname >/dev/null
fi

host=`sudo grep -E ^127\.0\.1\.1 $mydir/etc/hosts`
if [ $? -eq 0 ]; then
    echo $host | grep "$puppetmasterfqdn" >/dev/null
    if [ $? -eq 0 ]; then
        echo "Puppet master's name is correctly set in hosts!"
    else
        sudo sed -i.old "s/^127\.0\.1\.1\s*/127.0.1.1 $puppetmasterfqdn /" $mydir/etc/hosts
    fi
else
    echo "127.0.1.1\t$puppetmasterfqdn" | sudo tee -a $mydir/etc/hosts >/dev/null
fi


#Montowanie puppet.git

sudo mkdir -p $mydir/mnt/puppet.git
sudo grep rootfs/mnt/puppet.git $mydir/../fstab >/dev/null
if [ $? -eq 0 ]; then
    echo "Puppet git repository is already mounted!"
else
    echo "$gitlocation $mydir/mnt/puppet.git none bind 0 0" | sudo tee -a $mydir/../fstab  >/dev/null
    sudo lxc-info -n $puppetmaster |grep RUNNING >/dev/null
    if [ $? -eq 0 ]; then
        sudo lxc-stop -n $puppetmaster
    fi
fi



#Network setup
sudo grep $puppetip $mydir/etc/network/interfaces >/dev/null
if [ $? -eq 0 ]; then
    echo "Static ip on the container is already set!"
else
    sudo sed -i "iface eth0 inet dhcp/iface eth0 inet static \naddress $puppetip\nnetmask 255.255.255.0\ngateway $puppetgetewayip/" $mydir/etc/network/interfaces
fi



#Container startup

sudo lxc-info -n $puppetmaster |grep RUNNING >/dev/null
if [ $? -eq 0 ]; then
    echo "Container is '$puppetmaster' already running!"
else
    sudo lxc-start -d -n $puppetmaster
    sleep 5
fi


#Learning the assigned dynamic IP. Static IP will be assigned later.

myip=`sudo lxc-info -n $puppetmaster -i | grep -oE "[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}"`
echo "puppetmaster IP = $myip"


#Preparing the puppet's configuration bare repository for cross-container mount

mount | grep $gitlocation >/dev/null
if [ $? -eq 0 ]; then
    echo "Mount point '$gitlocation' is already declared"
else
    sudo mount --bind $gitlocation $gitlocation
    sudo mount --make-unbindable $gitlocation $gitlocation
    sudo mount --make-shared $gitlocation $gitlocation
fi


#Puppet release.deb

if sudo [ -f $mydir/tmp/puppetdeb.deb ]; then
    echo "Puppet release deb already exists!"
else
    sudo wget -O $mydir/tmp/puppetdeb.deb http://apt.puppetlabs.com/puppetlabs-release-$mycodename.deb
fi


#Second stage script

sudo tee $mydir/tmp/bootstrap-puppetmaster-insider.sh >/dev/null <<EOT
#!/bin/bash

getent passwd $puppetuser >/dev/null
if [ \$? -eq 0 ]; then
    echo "user $puppetuser already exists"
else
    usermod -l $puppetuser -d /home/$puppetuser ubuntu
    groupmod -n $puppetuser ubuntu
    sudo mv /home/ubuntu /home/adam
fi

if [ -d /home/$puppetuser/.ssh ]; then
    echo "'.ssh' folder already exists"
    sudo chown $puppetuser:$puppetuser /home/$puppetuser/.ssh
else
    sudo mkdir -p /home/$puppetuser/.ssh
    sudo chown $puppetuser:$puppetuser /home/$puppetuser/.ssh
    sudo chmod 0700 /home/$puppetuser/.ssh
fi

id $puppetuser | grep sudo >/dev/null
if [ \$? -eq 0 ]; then
    echo "user $puppetuser already is a sudoer"
else
    sudo usermod -a -G sudo $puppetuser
fi


if [ -f /home/$puppetuser/.ssh/authorized_keys ]; then
    echo "File .ssh/authorized_keys already exists"
else
    sudo -u $puppetuser touch /home/$puppetuser/.ssh/authorized_keys
fi

sudo grep "$puppetauth" /home/$puppetuser/.ssh/authorized_keys >/dev/null

if [ \$? -eq 0 ]; then
    echo "proper key in authorized_keys already present"
else
    echo $puppetauth | sudo -u $puppetuser tee /home/$puppetuser/.ssh/authorized_keys >/dev/null
fi

sudo dpkg -s puppetlabs-release>/dev/null
if [ \$? -eq 0 ]; then
    echo "puppetlabs-release is already installed!"
else
    sudo dpkg -i /tmp/puppetdeb.deb
fi

sudo dpkg -s puppetmaster>/dev/null
if [ \$? -eq 0 ]; then
    echo "puppetlabsmaster is already installed!"
else
    sudo apt-get update
    sudo apt-get --yes install puppetmaster
fi

sudo dpkg -s git>/dev/null
if [ \$? -eq 0 ]; then
    echo "git already installed!"
else
    sudo apt-get --yes install git
    sudo -u $puppetuser git config --global push.default simple
fi


sudo puppet module list|grep  puppetlabs-puppetdb>/dev/null
if [ \$? -eq 0 ]; then
    echo "PuppetDB module already installed!"
else
    sudo puppet module install puppetlabs-puppetdb
fi

sudo puppet agent --test --server $puppetmasterfqdn

sudo puppet apply /tmp/puppetdb.pp

if [ -d /etc/puppet/.git ]; then
    echo "Git repository is already clonned!"
else
    if [ -d /etc/puppet.old ]; then
        sudo rm -r /etc/puppet.old
    fi
    sudo mv /etc/puppet /etc/puppet.old
    user=`whoami`
    sudo git clone /mnt/puppet.git /etc/puppet
    sudo chown -R $puppetuser:$puppetuser /etc/puppet
fi

grep "export LANG=C.UTF-8" /etc/default/puppetmaster >/dev/null
if [ \$? -eq 0 ]; then
    echo "UTF-8 is properly set"
else
    echo "export LANG=C.UTF-8" | sudo tee -a /etc/default/puppetmaster
    sudo service puppetmaster restart
fi

sudo chown -R $puppetuser:$puppetuser /home/$puppetuser

EOT

sudo tee $mydir/tmp/puppetdb.pp >/dev/null <<'EOT'
node puppetmaster {
  # Configure puppetdb and its underlying database
  class { 'puppetdb': database => 'embedded'}
  # Configure the puppet master to use puppetdb
  class { 'puppetdb::master::config': }
}
EOT

sudo chmod +x $mydir/tmp/bootstrap-puppetmaster-insider.sh


# Disabling use of DNS on ssh

sudo lxc-attach -n $puppetmaster -- bash -x "/tmp/bootstrap-puppetmaster-insider.sh"

tmp=$(sudo grep -E '^UseDNS' $mydir/etc/ssh/sshd_config)
if [ $? -eq 0 ]; then
    echo $tmp | grep UseDNS >/dev/null
    if [ $? -eq 0 ]; then
        echo "Puppet master's sshd is correctly configured to skip reverse DNS!"
    else
        sudo sed -i.old "s/^\s*UseDNS\s*.*$/UseDNS no/" $mydir/etc/ssh/sshd_config
    fi
else
    echo "UseDNS no" | sudo tee -a $mydir/etc/ssh/sshd_config >/dev/null
    sudo lxc-attach -n $puppetmaster -- service ssh restart
fi


tmp=$(sudo grep -E '^iface eth0 inet dhcp$' $mydir/etc/network/interfaces)
if [ $? -eq 0 ]; then
    sudo sed -i.old "s/iface eth0 inet dhcp/iface eth0 inet static\naddress $puppetip \nnetmask 255.255.255.0 \ngateway $puppetgetewayip/" $mydir/etc/network/interfaces
else
    tmp=$(sudo grep -E '^iface eth0 inet static$' $mydir/etc/ssh/sshd_config)
    if [ $? -eq 0 ]; then
        echo "Networking is already configured with static IP on $puppetmaster!"
    else
        echo "### Cannot configure static IP on $puppetmaster! Please configure networking manually."
    fi
fi

tmp=$(sudo grep -E '^iface eth0 inet static$' $mydir/etc/ssh/sshd_config)


echo "puppetmaster IP = $myip"

 

 

Sign in to leave a comment