When automating Java and Tomcat installations with Puppet, we often need to configure environment variables like JAVA_HOME in system-wide configuration files. The /etc/profile file is executed for login shells, making it an ideal place to set these variables.
The most elegant solution is to use the file_line
resource from Puppet's stdlib module. First ensure you have the module installed:
puppet module install puppetlabs-stdlib
Here's a complete example that installs the packages and configures JAVA_HOME:
# Install required packages
package { [
"openjdk-6-jdk",
"openjdk-6-doc",
"openjdk-6-jre",
"tomcat6",
"tomcat6-admin",
"tomcat6-common",
"tomcat6-docs",
"tomcat6-user"
]:
ensure => present,
}
# Ensure JAVA_HOME is set in /etc/profile
file_line { 'set_java_home':
path => '/etc/profile',
line => 'JAVA_HOME="/usr/lib/java"\nexport JAVA_HOME',
match => '^JAVA_HOME=',
}
If you prefer not to use stdlib, you can manage the entire file:
file { '/etc/profile':
ensure => file,
content => "# Original /etc/profile content\nJAVA_HOME=\"/usr/lib/java\"\nexport JAVA_HOME",
# Or use source => 'puppet:///modules/profile/profile_with_java'
}
- Use file_line for minor modifications to avoid overwriting other configurations
- Consider using /etc/environment for simpler variable declarations
- For production, manage these variables in a dedicated profile.d script
After Puppet runs, verify with:
source /etc/profile
echo $JAVA_HOME
When managing Java and Tomcat installations with Puppet, setting environment variables like JAVA_HOME is a common requirement. The challenge lies in modifying system-wide configuration files like /etc/profile in an idempotent way - ensuring the changes persist without causing duplicate entries.
The most elegant solution is to use Puppet's file_line
resource from the stdlib module. This allows you to append lines to files while checking for duplicates:
file_line { 'set_java_home':
path => '/etc/profile',
line => 'JAVA_HOME="/usr/lib/jvm/default-java"',
match => '^JAVA_HOME=',
}
file_line { 'export_java_home':
path => '/etc/profile',
line => 'export JAVA_HOME',
match => '^export JAVA_HOME',
require => File_line['set_java_home'],
}
Here's how to combine this with your existing package installation:
package { [
'openjdk-6-jdk',
'openjdk-6-doc',
'openjdk-6-jre',
'tomcat6',
'tomcat6-admin',
'tomcat6-common',
'tomcat6-docs',
'tomcat6-user'
]:
ensure => present,
}
file_line { 'set_java_home':
ensure => present,
path => '/etc/profile',
line => 'JAVA_HOME="/usr/lib/jvm/default-java"',
match => '^JAVA_HOME=',
require => Package['openjdk-6-jdk'],
}
file_line { 'export_java_home':
ensure => present,
path => '/etc/profile',
line => 'export JAVA_HOME',
match => '^export JAVA_HOME',
require => File_line['set_java_home'],
}
Using Augeas
For more complex modifications, Augeas provides a powerful alternative:
augeas { 'set_java_environment':
context => '/files/etc/profile',
changes => [
'set JAVA_HOME "\"/usr/lib/jvm/default-java\""',
'set export[. = "JAVA_HOME"] "JAVA_HOME"',
],
onlyif => 'match export[. = "JAVA_HOME"] size == 0',
}
Template Approach
For complete control, you can manage the entire file as a template:
file { '/etc/profile':
ensure => file,
content => template('profile/profile.erb'),
mode => '0644',
}
This requires maintaining a complete template file, which might be overkill for simple additions.
After applying these changes, verify them with:
puppet agent --test
source /etc/profile
echo $JAVA_HOME