Installing an RPM with an Environment Variable using Puppet

Dealing with an RPM that uses an environment variable to accept an EULA when performing automated installations with Puppet.

Installing an RPM with an Environment Variable using Puppet
Photo by Mohammad Rahmani / Unsplash

I was setting up the Microsoft ODBC driver for SQL Server 18 packages to be installed via Puppet, but I ran into an error using Puppet's standard package library:

/var/tmp/rpm-tmp.AWH34t: line 17: /dev/tty: No such device or address

A quick peek at the rpm scripts showed me the problem - the rpm install script was trying to output the EULA to the terminal, but the Puppet agent doesn't have one:

rpm -qlp --scripts msodbcsql18-18.3.2.1-1.x86_64.rpm

check_eula_acceptance()
{
    if [ "$ACCEPT_EULA" != "y" ] && [ "$ACCEPT_EULA" != "Y" ]; then
        exec 2&>/dev/tty 1>&2 </dev/tty
        echo "The license terms for this product can be downloaded from"

You can automatically accept the EULA by setting the environment variable export ACCEPT_EULA=y, but Puppet's package module doesn't have a way to pass in environment variables.

Instead, I can install the rpms manually, using rpm and the exec module. The specific version is needed to prevent Puppet from running the install on each Puppet agent run - I use unless to grep the output of rpm -qa, and if it's present, the exec command doesn't run. If it's not, rpm -U [the_package.rpm] is run, installing the rpm manually. The require commands ensure the commands are run in the correct order.

# Definding the rpm versions and names
msodbc_ver: 'msodbcsql18-18.3.2.1-1.x86_64'
mssql_ver: 'mssql-tools18-18.2.1.1-1.x86_64'

# unixODBC is a dependency for msodbcsql18
package { 'unixODBC':
  ensure   => 'present',
  name     => 'unixODBC',
  provider => 'dnf',
}

# Manually install the rpms
# The rpms require acceptance of an EULA, and there doesn't appear to be a way to pass
# an environment variable into the package module. Instead, we manually run the rpm
# command. The "unless" option is run prior to executing anything, and nothing will be
# executed if the unless returns successful (0). Unless is set to query rpm , and then
# we grep for package we're installing. Grep will return 1 if the package isn't installed.
exec { 'install msodbcsql18':
  environment => ['ACCEPT_EULA=Y'],
  unless      => "/usr/bin/rpm -qa | /usr/bin/grep -q ${msodbc_ver}",
  command     => "/usr/bin/rpm -U http://myserver/${msodbc_ver}.rpm",
  require     => Package['unixODBC'],
}

exec { 'install mssql-tools':
  environment => ['ACCEPT_EULA=Y'],
  unless      => "/usr/bin/rpm -qa | /usr/bin/grep -q ${mssql_ver}",
  command     => "/usr/bin/rpm -U http://myserver/${mssql_ver}.rpm",
  require     => Exec['install msodbcsql18'],
}