As part of my work I need to be able to test different Java Web applications. I need to be able to run some tests on more then only single computer, hence I need rapid way of setting up several Linux based computers/servers with configured Java running, usually I’m using Ubuntu based destributives.

Therefore I’ve choose the winning couple of Puppet and Vagrant. You’re more than welcome to read about these tools and I’ll skip the installation guide for them, since google has pleanty of different tutorials explaning how to do it for different platform, so you just need to pick the right one for you.

I’m going to show how to leverage Puppet modules architecture, how to implement new module which will be capable to install and configure Java for new VM machine. To learn more about modules in Puppet, please take a look on modules fundamentals article on Puppet labs site.

1. Download Java.

Very first step which has to be done, is to download tar gz archive of Java JDK or (JRE), from Oracle official site. By the time I’m writting this post current lates JDK tar gz is jdk-7u40-linux-i586.tar.gz.

2. Create new Puppet module.

Terminal Window
1
mkdir -p modules/java/{files,manifests}

3. Copy Java JDK into module folders.

Terminal Window
1
cp jdk-7u40-linux-i586.tar.gz modules/java/files/

4. Write module implementation.

  • Create init.pp file within manifests folder
Terminal WIndow
1
touch modules/java/manifests/init.pp
  • Now we need to write down following content:
init.pp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
class java(
    $java_archive = "jdk-7u40-linux-x64.tar.gz",
    $java_home = "/usr/lib/jvm/jdk1.7.0_40/",
    $java_folder = "jdk1.7.0_40")
    {

    Exec {
        path => [ "/usr/bin", "/bin", "/usr/sbin"]
    }

    file { "/tmp/${java_archive}" :
        ensure => "present",
        source => "puppet:///modules/java/${java_archive}",
        owner  => vagrant,
        mode   => 755
    }

    exec { 'extract jdk':
        cwd => '/tmp',
        command => "tar xfv ${java_archive}",
        creates => $java_home,
        require => File["/tmp/${java_archive}"],
    }

    file { '/usr/lib/jvm' :
        ensure => directory,
        owner => vagrant,
        require => Exec['extract jdk']
    }

    exec { 'move jdk':
        cwd => '/tmp',
        creates => $java_home,
        require => File['/usr/lib/jvm'],
        command => "mv ${java_folder} /usr/lib/jvm/"
    }

    exec {'install java':
        require => Exec['move jdk'],
        logoutput => true,
        command => "update-alternatives --install /bin/java java ${java_home}/bin/java 1"
    }

    exec {'set java':
        require => Exec['install java'],
        logoutput => true,
        command => "update-alternatives --set java ${java_home}/bin/java"
    }

    exec {'install javac':
        require => Exec['move jdk'],
        logoutput => true,
        command => "update-alternatives --install /bin/javac javac ${java_home}/bin/javac 1"
    }

    exec {'set javac':
        require => Exec['install javac'],
        logoutput => true,
        command => "update-alternatives --set javac ${java_home}/bin/javac"
    }

  file { "/etc/profile.d/java.sh":
      content => "export JAVA_HOME=${java_home}
                  export PATH=\$PATH:\$JAVA_HOME/bin"
  }
}

5. Run and test new module.

  • Run:
Terminal Window
1
vagrant init
  • Edit Vagrantfile, put following content:
Vagrantfile
1
2
3
4
5
6
7
8
9
10
11
12
13
Vagrant::Config.run do |config|
  config.vm.define :test_vm do |test_vm|
        test_vm.vm.box = "ubuntu"
        test_vm.vm.network :hostonly, "10.71.71.10"
        test_vm.vm.customize [ "modifyvm", :id, "--memory", "1024"]
        test_vm.vm.provision :puppet do |puppet|
                puppet.module_path = "~/vagrant/manifests/"
                puppet.module_path = "modules"
                puppet.manifests_path = "manifests"
                puppet.manifest_file  = "test_vm.pp"
        end
  end
end
  • Create manifests folder and test_vm.pp:
Terminal Window
1
2
mkdir manifests && touch manifests/test_vm.pp
echo "include java" >> manifests/test_vm.pp
  • Run VM
Terminal Window
1
vagrant up test_vm

6. Enjoy!

PS. Thanks to my friend which pointed me to more nice and clear way of declaring variable in a class in a way it could be customized later with values different from defaults. I’ve update the post and here you can see the customization example:

test_vm.pp
1
2
3
4
5
class { "java":
    java_archive => "jdk-8u01-linux-x64.tar.gz",
    java_home => "/usr/lib/jvm/jdk1.8.0_01/",
    java_folder => "jdk1.8.0_01")
}