Search code examples
puppetpuppetlabs-mysql

puppetlabs-mysq (v3.0.0): temporary user


we have a puppet setup that basically works like this:

  1. Create user "puppetdeploy"
  2. Grant access to all tables for user "puppetdeploy"
  3. Runs scripts that creates and updates databases from .sql files, using 'puppetdeploy'
  4. Revoke all access to user 'puppetdeploy'

.pp file looks something like this:

mysql_user { 'puppetdeploy@localhost':
   ensure => 'present',
   password_hash => '*****',           
}->
mysql_grant { 'grant_all_for_puppetdeploy':
   ensure     => 'present',
   options    => ['GRANT'],
   privileges => ['ALL'],
   table      => '*.*',
   user       => 'puppetdeploy@localhost',
}
#... execute scripts to import bunch of .sql files using mysql user 'puppetdeploy'
mysql_grant { 'revoke_all_for_puppetdeploy':
   options    => ['REVOKE'],
   privileges => ['ALL'],
   table      => '*.*',
   user       => 'puppetdeploy@localhost',
}   

In later versions of the mysql-module this no longer works, as name for each grant need to be in format '[user]/[table]', and I'm not allowed to have same name for two or more mysql_grants.

Are there any ways to work around this restriction in puppetlabs-mysql 3.0.0, or are there better ways to deal with temporary mysql users?


Solution

  • The issue is that such workflows are an ill fit with Puppet's paradigm. A Puppet manifest is not a script. It's a description of state that you want Puppet to enforce. Of course, transitions often require serialized configuration steps to get right, but everything should have one definite state that Puppet has to synchronize to, and it should stay in this state.

    All workflows that require one or more resources to take several different states during the same Puppet transactions pose difficulties, and will usually be solved through some kind of hack.

    In your specific scenario, it might be best to forgo the mysql_grant type in favor of a script that Puppet deploys and runs, which will do all the steps that are outlined in your manifest excerpt. It's not a very Puppet-y thing to do, but much cleaner, because you don't try and make Puppet juggle the same resource from one state to another.

    Better yet, enable Puppet to use the privileges of an actual administrative account.

    As a compromise, you could add a custom fact that will allow Puppet to determine that all GRANTs are in order at the start of a followup transaction, and remove the user then.

    if $grants_are_deployed {
        mysql_grant { 'revoke_all_for_puppetdeploy': ... }
    else {
        mysql_user { 'puppetdeploy@localhost': }
    }