<![CDATA[wegotoeleven]]>https://blog.wegotoeleven.co.uk/https://blog.wegotoeleven.co.uk/favicon.pngwegotoelevenhttps://blog.wegotoeleven.co.uk/Ghost 5.12Mon, 29 Aug 2022 20:44:01 GMT60<![CDATA[30 Steps to Vagrant and VMWare Fusion Awesomeness]]>

Vagrant is pretty cool, but of late I've been having real issues finding a Vagrant base box that works with VMware Fusion OOTB. My blogging workflow (used to) involve(s) using a Vagrant box with Jekyll to generate a static site on my local Mac, and then uploading

]]>
https://blog.wegotoeleven.co.uk/30-steps-to-vagrant-and-vmware-fusion-awesomeness/630d24d2e5743e0001ee9c70Mon, 02 Mar 2020 18:00:00 GMT

Vagrant is pretty cool, but of late I've been having real issues finding a Vagrant base box that works with VMware Fusion OOTB. My blogging workflow (used to) involve(s) using a Vagrant box with Jekyll to generate a static site on my local Mac, and then uploading to an S3 bucket. The Vagrant Jekyll boxes weren't up to scratch, so I've decided to figure out how to create my own.

This guide covers how to create the box and add it to your list of boxes, for use in specifying within a Vagrantfile. It doesn't cover Vagrant fundementals, so I assume that you'll have some basic knowledge in how it works before embarking on this magical quest.

  1. Open VMware Fusion

  2. Select “Install from disc or image” and click "Continue"

  3. Locate the ISO for the distribution you want to install, then select “Open”, and click "Continue".

  4. Unselect the checkbox for “Use Easy Install”

  5. Choose “Customize Settings”, and enter a name for the VMware file (name/OSarch, i.e. wegotoeleven/trusty64) and select “Save"

  6. Customise the VM’s settings

    1. Turn on Shared Folders
    2. Set memory to desired size, at least 1024MB
    3. Change the Networking to "Share with my Mac" (aka NAT)
    4. Change the disk size to 40 GB and deselect “Split into 2GB files”
    5. Turn off the sound card
    6. Expand "Advanced USB options" and select "Remove USB Controller"
    7. Untick "Share Mac printers with Linux"
  7. Boot the VM, install the Guest OS and customise the following settings when prompted:

  8. Host Name: Same as the second part of the name of the VMware file (i.e. trusty64)

  9. Full Name: vagrant

  10. User: vagrant

  11. Password: vagrant

  12. Once setup and at the command prompt, login and change the Root Password. When asked, set to vagrant

    $ sudo passwd root
    
  13. Update the OS because updates

    $ sudo apt update && sudo apt upgrade -y
    
  14. Update the Sudoers file with the following to allow the vagrant user sudo rights without having to authenticate with a password

    #Defaults !visiblepw
    Defaults env_keep="SSH_AUTH_SOCK"
    
  15. Test. Is the following command outputs the current directory instead of an error, all is good

    $ sudo pwd
    
  16. Restart VM

    $ sudo shutdown -r now
    
  17. Make ssh folder

    $ mkdir ~/.ssh
    
  18. Set permissions

    $ chmod 700 ~/.ssh
    
  19. Download Vagrant authorised keys

    $ wget --no-check-certificate https://raw.github.com/mitchellh/vagrant/master/keys/vagrant.pub -O ~/.ssh/authorized_keys
    
  20. Set permissions on authorised keys file

    $ chmod 600 ~/.ssh/authorized_keys && chown -R vagrant ~/.ssh
    
  21. Install OpenSSH

    $ sudo apt install openssh-server -y
    
  22. Edit the SSH config file

    $ sudo nano /etc/ssh/sshd_config
    
  23. Restart SSH service

    $ sudo service ssh restart
    
  24. Install VMware Tools. Begin by mounting the VMware Tools by selecting Virtual Machines > Install VMware Tools from the menu bar menu

    $ sudo mkdir -p /mnt/cdrom
    $ sudo mount /dev/cdrom /mnt/cdrom
    $ tar xzvf /mnt/cdrom/VMwareTools-9.2.2-893683.tar.gz -C /tmp
    $ cd /tmp/vmware-tools-distrib/
    $ sudo ./vmware-install.pl\
    
  25. Wipe the free space on the VM to stop fragmentation

    $ sudo dd if=/dev/zero of=/EMPTY bs=1M
    $ sudo rm -f /EMPTY
    
  26. Shutdown the VM

    $ sudo shutdown -h now
    
  27. Navigate to the location of your vmwarevm. By default this location is ~/Virtual Machines/.

    $ cd ~/Virtual Machines/wegotoeleven:xenial64.vmwarevm
    

    Note: Any forward slashes (/) will be translated into colons if the name of the VMware file contains a forward slash

  28. Create a file named metadata.json and enter the following contents:

    {
      "provider": "vmware_fusion"
    }
    
  29. Create a file named Vagrantfile and enter the following contents.

    # -*- mode: ruby -*-
    # vi: set ft=ruby
    
    Vagrant.configure("2") do |config|
      config.vm.provider :vmware_fusion do |v, override|
        v.gui = false
      end
    end
    
  30. We next want to optimize the box to reduce it’s size:

    $ /Applications/VMware\ Fusion.app/Contents/Library/vmware-vdiskmanager -d Virtual\ Disk.vmdk
    $ /Applications/VMware\ Fusion.app/Contents/Library/vmware-vdiskmanager -k Virtual\ Disk.vmdk
    
  31. Finally compress the box:

    $ tar cvzf package.box ./
    
  32. Add the box to Vagrant

    $ vagrant box add wegotoeleven/xenial64 package.box
    

I couldn't have done this without the following blog posts:

And yeah. I know I said 30.

]]>
<![CDATA[Puppet puppetdb and puppet agent]]>

I like the idea of desired state management systems. You define a set of criteria, and your devices will indefinitely match that criteria, returning to the "Desired State" if required. I've done this a few times with Jamf Pro, using smart groups, extension attributes and policies

]]>
https://blog.wegotoeleven.co.uk/puppet-puppetdb-and-puppet-agent/630d2497e5743e0001ee9c5dWed, 03 May 2017 21:20:00 GMT

I like the idea of desired state management systems. You define a set of criteria, and your devices will indefinitely match that criteria, returning to the "Desired State" if required. I've done this a few times with Jamf Pro, using smart groups, extension attributes and policies to "mimic" the functionality of a desired state management system (which was nice) but I wanted to really get to grips with a system that's explicitly designed for this purpose. Enter the king of "Desired State" - Puppet.

In an effort to get to know Puppet, I need to build out some infrastructure. Yeah, I know there's a learning VM (that's really awesome, by the way), but I learn by experience. What better way than to build my own.

Assumptions

I'm not going to get into the nitty gritty of what puppet actually is and does, and I'm going to assume that if you're reading this post, you:

  1. Understand what Desired State is
  2. Understand (roughly) what Puppet is and can do
  3. Are poor / nuts, and would rather build and spin up your own servers, rather than using Puppet's Enterprise version (which is still totally viable, but I'm a masochist)

For the purposes of this example, I will setup 3 VMs and use the following defaults:

  • VMware Fusion 8.5.6 to host the VMs
    • Network set to custom "vmnet2" network
      • NAT
      • "Connect Host Mac to this network"
      • Provide DHCP, subnet 10.0.1.0/24
  • Puppet Server
    • Ubuntu 16.04
    • 2 x CPU Cores
    • 3072MB Memory
    • 50GB HDD (thin provisioned)
    • Hostname puppet-server
    • IP Address 10.0.1.129
  • Puppet Database Server
    • Ubuntu 16.04
    • 2 x CPU Cores
    • 3072MB Memory
    • 50GB HDD (thin provisioned)
    • Hostname puppet-db
    • IP Address 10.0.1.130
  • Puppet Test Client
    • macOS 10.12.4
    • 2 x CPU Cores
    • 8192MB Memory
    • 50GB HDD (thin provisioned)
    • Hostname puppet-client
    • IP Address 10.0.1.128

Obviously, if you're following along with me, feel free to change any of the above defaults, but please make sure you're changing them in the instructions below.

Network Configuration

  1. Spin up your boxes with the above config, and set each device up to allow access via SSH (cause it's easier like)

  2. Rename both servers by editing the hostname file on each device, and adding the desired hostname

    $ sudo vi /etc/hostname
    
  3. In addition, add the hostname into the hosts file, pointing to the loopback (127.0.0.1) address under the blog.wegotoeleven.co.uk entry

    $ sudo vi /etc/hosts
    
    127.0.0.1       blog.wegotoeleven.co.uk
    127.0.0.1       puppet-db
    
  4. In an environment without proper DNS, do the following:
    4. Set each device with a static IP address. I'm using the IP addresses specified above.

     ```bash
     $ sudo vi /etc/network/interfaces
     ```
     ```
     # The primary network interface
     		auto eth0
     		iface eth0 inet static
     		address 10.0.0.41
     		netmask 255.255.255.0
     		network 10.0.0.0
     		broadcast 10.0.0.255
     		gateway 10.0.0.1
     		dns-nameservers 10.0.0.1 8.8.8.8
     ```
    
    • Add each device into the each device's hosts file

      $ sudo vi /etc/hosts
      
      10.0.1.129    puppet-server
      10.0.1.130    puppet-db
      10.0.1.128    puppet-client
      

Puppet Server Configuration

  1. Install the NTP service on the Puppet server, because Puppet uses an NTP source when issuing certificates to it's nodes

    $ sudo apt install ntp
    
  2. Add the Puppet repositories to the Puppet Server

    $ wget https://apt.puppetlabs.com/puppetlabs-release-pc1-xenial.deb
    $ sudo dpkg -i puppetlabs-release-pc1-xenial.deb
    $ sudo apt update
    
  3. Install puppetserver on the Puppet Server (duh)

    $ sudo apt install puppetserver
    
  4. In addition, install the "puppetdb-termini" package to enable the Puppet server to talk to the Puppet DB server

    $ sudo /opt/puppetlabs/puppet/bin/puppet resource package puppetdb-termini ensure=latest
    
  5. Create the required configuration files on the Puppet server for the connections to the PuppetDB:

    • routes.yaml:

      $ sudo vi /etc/puppetlabs/puppet/routes.yaml
      
      ---
      master:
          facts:
              terminus: puppetdb
              cache: yaml
      
    • puppetdb.conf:

      $ sudo vi /etc/puppetlabs/puppet/puppetdb.conf
      
      [main]
      server_urls = https://puppet-db:8081
      
  6. Edit puppet.conf

    $ sudo vi /etc/puppetlabs/puppet/puppet.conf
    
    [master]
    storeconfigs = true
    storeconfigs_backend = puppetdb
    
  7. Ensure the permissions are correct on the Puppet configuration folder

    $ sudo chown -R puppet:puppet $(sudo /opt/puppetlabs/puppet/bin/puppet config print confdir)
    
  8. Set puppetserver to start automatically when the system starts

    $ sudo /opt/puppetlabs/puppet/bin/puppet resource service puppetserver ensure=running enable=true
    
  9. Restart the Server to pickup the above changes.

Puppet DB Server Configuration

  1. Add the Puppet repositories to the Puppet DB Server

    $ wget https://apt.puppetlabs.com/puppetlabs-release-pc1-xenial.deb
    $ sudo dpkg -i puppetlabs-release-pc1-xenial.deb
    
  2. Install the Database backend for PuppetDB

    $ sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt/ `lsb_release -cs`-pgdg main" >> /etc/apt/sources.list.d/pgdg.list'
    $ wget -q https://www.postgresql.org/media/keys/ACCC4CF8.asc -O - | sudo apt-key add -
    $ sudo apt update
    $ sudo apt install postgresql postgresql-contrib
    
  3. Setup PostgreSQL on the Puppet DB Server

    $ sudo -u postgres sh
    
    createuser -DRSP puppetdb
    createdb -E UTF8 -O puppetdb puppetdb
    psql puppetdb -c 'create extension pg_trgm'
    exit
    
  4. Restart the PostgreSQL service

    $ sudo service postgresql restart
    
  5. Test PostgreSQL. If this is successful, you'll be dropped into PostgreSQL. Use \q to exit.

    $ psql -h blog.wegotoeleven.co.uk puppetdb puppetdb
    
  6. To configure PuppetDB to use this database, add the following details to the puppetdb database configuration file. In this example, I'm using super secret usernames and passwords. Don't do this if you're planning on setting this up in prod.

    $ sudo vi /etc/puppetlabs/puppetdb/conf.d/database.ini
    
    subname = //blog.wegotoeleven.co.uk:5432/puppetdb
    username = puppetdb
    password = puppetdb
    

    For the subname, replace the hostname with the DB server’s hostname (or blog.wegotoeleven.co.uk if the PostgreSQL service is running on the same server), replace the port with the port on which PostgreSQL is listening (usually 5432), and replace the database with the name of the database you’ve created for use with PuppetDB. In addition, uncomment the following sections:

    classname
    subprotocol
    gc-interval
    

Connecting the servers together

  1. Install the Puppet Agent on the Puppet DB Server

    $ sudo apt install puppet-agent
    
  2. On the Puppet DB server, set the name of the server that the agent should connect to, replacing the server with the required hostname of the Puppet server

    $ sudo vi /etc/puppetlabs/puppet/puppet.conf
    
    server = puppet-server
    
  3. Enrol the Puppet DB Server into Puppet

    $ sudo /opt/puppetlabs/puppet/bin/puppet agent --test --waitforcert 60
    
  4. On the Puppet Server, check to see whether the Puppet DB server has requested a certificate

    $ sudo /opt/puppetlabs/puppet/bin/puppet cert --list
    
  5. You should see the name of the Puppet DB server, followed by some other stuff. Accept the cert request

    $ sudo /opt/puppetlabs/puppet/bin/puppet cert --sign puppet-db
    
  6. On the Puppet DB server, install the puppetdb service

    $ sudo /opt/puppetlabs/puppet/bin/puppet resource package puppetdb ensure=latest
    
  7. Stop the puppetdb service and setup SSL

    $ sudo service puppetdb stop && sudo /opt/puppetlabs/bin/puppetdb ssl-setup
    
  8. Ensure the puppetdb service runs on reboot

    $ sudo /opt/puppetlabs/puppet/bin/puppet resource service puppetserver ensure=running enable=true
    
  9. Restart the Puppet DB server

  10. Check the PuppetDB logs on the Puppet DB server to verify that it's working

    $ sudo cat /var/log/puppetlabs/puppetdb/puppetdb.log
    

Enrolling a macOS client

  1. Install the puppet agent onto the Puppet Client, by downloading the specific version as per the OS version, from here

  2. Install the download pkg file. When asked, specify the hostname of the server and the client

  3. Open Terminal

  4. Edit the Puppet configuration file and add the following contents

    $ sudo vi /etc/puppetlabs/puppet/puppet.conf
    
    [main]
    logdir=/var/log/puppet
    vardir=/var/lib/puppet
    ssldir=/var/lib/puppet/ssl
    #rundir=/var/run/puppet
    factpath=$vardir/lib/facter
    templatedir=$confdir/templates
    
    [master]
    ssl_client_header = SSL_CLIENT_S_DN
    ssl_client_verify_header = SSL_CLIENT_VERIFY
    
    [agent]
    server=puppet-server
    certname=puppet-client
    report=true
    pluginsync=true
    
  5. Request a cert from the Puppet Server

    $ sudo /opt/puppetlabs/puppet/bin/puppet agent --waitforcert 60 --test
    
  6. On the Puppet DB server, run the log file and keep an eye on it

    $ sudo tail -f /var/log/puppetlabs/puppetdb/puppetdb.log
    
  7. Then, on the Puppet Server, check and sign the cert request from puppet-client

    $ sudo /opt/puppetlabs/puppet/bin/puppet cert --list
    $ sudo /opt/puppetlabs/puppet/bin/puppet cert --sign puppet-client
    
]]>
<![CDATA[Using Markdown to write Documentation]]>

I absolutely cannot stand writing documentation. Well, that's kind of a lie; I don't mind the actual writing, but I get too hung up on trying to make it look pretty. If you—the reader—write your own, then maybe you'll know

]]>
https://blog.wegotoeleven.co.uk/using-markdown-to-write-documentation/630d246be5743e0001ee9c4cMon, 28 Sep 2015 18:00:00 GMT

I absolutely cannot stand writing documentation. Well, that's kind of a lie; I don't mind the actual writing, but I get too hung up on trying to make it look pretty. If you—the reader—write your own, then maybe you'll know what I mean.

One of the best things about writing docs that'll be hosted on-line is that the format will be based upon the site that it lives in. Take Github for example; all documentation up there looks the same. This is because they're all written in Markdown. Markdown is a language syntax that standardises formatting which allows a writer to focus on the content that's being written. If you've never seen a Github readme, check out a few:

This blog is also written in markdown. The CSS on this blog is used to apply styles to the various components of a converted markdown document. I'm not going to go into every piece of Markdown syntax as it's not the point of this post, but hopefully you get the idea.

So how cool would it be to leverage this when writing printed documentation?

Let's get one thing straight; Markdown was build for web rendering. So out of the box, there's no easy way to create a document in Markdown, and export to, say, PDF or Word document.

That's where Pandoc comes in.

Pandoc is a tool that converts files from one markup format to another. It's a downloadable application for Mac, Windows and Linux that runs in the command line in the format of:

$ pandoc -f ${input-format} ${input-file} \
    -t ${output-format} -o ${output-file}

As standard, it uses a predefined format when it spits out a Word document, that looks not unlike Word's default normal.dot. However, with the use of the --reference-docx option, you can specify a docx file that contains a custom format in order to format the output of the command.

For example:

$ pandoc -f markdown ~/Desktop/Documentation.markdown \
    -t docx -o ~/Desktop/Documentation.docx \
    --reference-docx ~/Desktop/Reference.docx

This will convert the file "Documentation.markdown" into a Word document called "Documentation.docx", using the reference file "Reference.docx"

So, about these reference docx files. "Where can I get them from" I hear you shout? Well, I've been rather unsuccessful in my attempts to find any. So I made my own! Here's one that looks like a rendered Markdown webpage. Plug this in to the above commands, and your markdown will "accurately" translate into printed documentation!

If you're a Markdown writer/user, and you have a hard time focusing on content rather than design, give this a go.

]]>