Search code examples
puppetlibrarian-puppet

How to chain classes with commands


I have the following class which installs mysql and sets up a user called user but when the create-database commands runs the user has not been created yet. How do i chain the commands so that the user is created before create-database tries to use it?

class { '::mysql::server':
  package_name            => 'mariadb-server.x86_64',
  root_password           => 'root',
  remove_default_accounts => true,
  override_options        => $override_options,
  restart                 => true,
  users                   => {
    'user@%' => {
      ensure                   => 'present',
      max_connections_per_hour => '0',
      max_queries_per_hour     => '0',
      max_updates_per_hour     => '0',
      max_user_connections     => '0',
      password_hash            => '...',
    }
  },
  grants                  => {
    'user@%/*.*' => {
      ensure     => 'present',
      options    => ['GRANT'],
      privileges => ['ALL'],
      table      => '*.*',
      user       => 'user@%',
    },
  }
}->
exec { 'create-database':
  creates => '/opt/dbinstalled',
  command => '/usr/bin/mysql -u user -puser < /create-db.sql'
}

I am using the puppetlabs-mysql package to install mysql.


Solution

  • You should take a look at the documentation for the require, before, subscribe, notify metaparameters. They are used to describe resource ordering (before, notify), or resource ordering and failure if the dependency fails (require, subscribe). Note the subscribe, notify metaparameters are only available for some resource types (exec, service, etc.).

    In this instance, you would do the following to chain a class:

    exec { 'create-database':
      creates => '/opt/dbinstalled',
      command => '/usr/bin/mysql -u user -puser < /create-db.sql',
      require => Class[::mysql::server],
    }
    

    But you really only need the dependency on the user resource:

    exec { 'create-database':
      creates => '/opt/dbinstalled',
      command => '/usr/bin/mysql -u user -puser < /create-db.sql',
      require => User[username or array of users],
    }
    

    Also you probably only want to create the database once, so we can give it a subscribe/refreshonly for idempotence:

    exec { 'create-database':
      creates     => '/opt/dbinstalled',
      command     => '/usr/bin/mysql -u user -puser < /create-db.sql',
      subscribe   => User[username or array of users],
      refreshonly => true,
    }
    

    Note that if you change the user resource that the create-database is subscribed to this will rerun the exec resource, so look into the unless, onlyif parameters for exec as other methods to establish idempotence.