Using Puppet to sync two directories

filespuppetscriptingsynchronization

I have a bunch of servers that have two directories on them that need to be in sync. For instance, on the same server I might have /var/path/to/dir1 and /var/path/to/dir2 which could have files and folders underneath of each. I'd like to sync /var/path/to/dir1 and have /var/path/to/dir2 as the "backup".

Does anyone know an efficient way in Puppet to sync these two directories? Would I have to create a custom script to do this and use the exec method in the Puppet manifest file?

My guess was to create a script to recursively verify the MD5 hash on every file in the primary directory and then verify the files in the second directory with that list. I wasn't sure if there was a way to do this in Puppet natively.

Best Answer

You were on the right track with puppet. Have the puppetmaster serve as the source of truth, house them in the server that runs your puppetmaster, and declare the files that should exist and the canonical versions there. You may even want to version the files that you are making available in the puppetmaster server using something like SVN or GIT.

This provides you some strong guarantees about what is in those two locations.

file { '/var/path/to/dir1/':
  ensure   => 'present',
  source   => 'puppet:///path/to/dir1',
  recurse  => 'true',
} 
file { '/var/path/to/dir2/':
  ensure   => 'present',
  source   => 'puppet:///path/to/dir1',
  recurse  => 'true',
}

As mentioned above, you may need to remove any collected unwelcome extras with something like

{
  purge => 'true',
  force => 'true',
}

As was pointed out to me (thanks!!), if there is a large number of files or a deep hierarchy of sub-folders under '/var/path/to/dir1/', the time to complete a puppet run could grow rapidly. I would still recommend to keep your puppet server as the source of truth, but you might do better to use rsync, something like:

rsync::get { '/var/path/to/dir1/':
  source  => 'puppet:///path/to/dir1',
  purge   => true,
}

rsync::get { '/var/path/to/dir2/':
  source  => 'puppet:///path/to/dir1',
  purge   => true,
}