Have puppet conditionally execute multiple commands

10,542

There are several ways to run exec only once, and only after "mysql_install_db-${name}" :

  • Just change the command line to add all the other commands (cmd1 && cmd2 && cmd3 ...).
  • Use the unless or onlyif parameters, so as to check if your stored procedure or whatsoever already exists before running the command. This might be complex, so another method is to have the command create a file ("command && touch /root/blah-${name}") and use the creates parameter.
  • Set refreshonly, and subscribe to the previous exec.

While all these solutions will work, you will not be respecting Puppet's spirit of describing the final state of your system. For database, user and grant settings you can use the puppetlabs-mysql module, that will let you describe them in a natural way. Stored resources are another matter, that might be packaged more logically with the application deployment process (as they must be kept in sync with the application). If this is not possible, then you can make your SQL scripts idempotent, using conditionals.

Share:
10,542

Related videos on Youtube

atxdba
Author by

atxdba

Updated on June 04, 2022

Comments

  • atxdba
    atxdba about 2 years

    I have a working puppet configuration to help installing mysql instances on a machine. My environment is setup such that there are multiple instances running on the same machine (with different configs/ports/etc).

    The basic setup I have in a manifest looks like

    File{
        owner => $owner,
        group => $group,
        before => Exec["mysql_install_db-${name}"],
    }
    
    exec{"mysql_install_db-${name}":
        creates => "/var/lib/mysql/${name}/mysql",
        command => "/usr/local/percona/mysql-${version}/usr/bin/mysql_install_db --user=mysql --datadir=/var/lib/mysql/${name} --basedir=/usr/local/percona/mysql-${version}/usr",
        logoutput => true,
    }
    

    This works perfectly fine, however now I'd like to modify this install process to run some subsequent commands to bootstrap the fresh install with some internal stored procedures and do some other 'prep work' we do for a new install.

    The commands would be basically like

    mysql -u user < /path/to/bootstrap1.sql
    mysql -u user < /path/to/bootstrap2.sql
    mysql -u user < /path/to/bootstrap3.sql
    

    I only want these run once, after the mysql_install_db command but somewhat under the same "creates" guard.

    I found some references to just passing an array to the command argument but that reference was in the form of a bug report of it not always working consistently.

    What's the preferred method to accomplish something like this, and ensure the commands get executed in a deterministic order and only after mysql_install_db was run?