How to Provision a Server with Java using Ansible
Nov 2018
In my post about how to provision any version of Java using a bash script, we saw that:
#!/bin/bash
# Get tarball for JDK 10.0.1
wget https://download.java.net/java/GA/jdk10/10.0.1/fb4372174a714e6b8c52526dc134031e/10/openjdk-10.0.1_linux-x64_bin.tar.gz
# make java 10 directory
mkdir -p /usr/lib/java10
# unpack tarball
tar -C /usr/lib/java10/ -xvzf ./openjdk-10.0.1_linux-x64_bin.tar.gz
# update alternatives
update-alternatives --install /usr/bin/java java /usr/lib/java10/jdk-10.0.1/bin/java 20000
update-alternatives --install /usr/bin/javac javac /usr/lib/java10/jdk-10.0.1/bin/javac 20000
# verify with a version check
java -version
Will get you openJDK version 10.0.1 from the tarball in the link.
While that script works, it's generally a better idea to make this more maintainable. For example, if we re-run this bash script on a server that is already provisioned, it will run all of these steps again. In this case, nothing bad will actually happen, but it can lead to some sticky debug sessions when we start to move to more complicated provisioning steps.
We'll convert this bash script to an ansible playbook. To test this, we'll set up a VagrantFile like so:
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/bionic64"
config.vm.network "private_network", ip: "192.168.56.115"
config.vm.provider :virtualbox do |vb|
vb.memory = 1024
vb.cpus = 1
end
config.vm.provision "ansible" do |ansible|
ansible.playbook = "provision.yml"
end
end
We'll need an ansible playbook in the same directory called "provision.yml". We are using Ubuntu 18 (bionic64), which does not come with python 2 installed. Since ansible defaults to python 2, one way to deal with that problem is to install it prior to running the playbook. We can't gather facts before installing it, because gathering facts requires, you guessed it, python 2:
---
- hosts: all
become: yes
gather_facts: no
pre_tasks:
- name: 'install python2 on ubuntu 18'
raw: test -e /usr/bin/python || (apt-get -y update && apt-get install -y python-minimal)
tasks:
- name: Gather facts
setup:
This bash command checks if we have python first, and only updates and gets python-minimal if it's not already there. The empty setup: command runs the gathering of facts and we can proceed like we never had to do this weird pre-provisioning step in the first place.
We can convert these two steps to:
# Get tarball for JDK 10.0.1
wget https://download.java.net/java/GA/jdk10/10.0.1/fb4372174a714e6b8c52526dc134031e/10/openjdk-10.0.1_linux-x64_bin.tar.gz
# make java 10 directory
mkdir -p /usr/lib/java10
To:
- name: Get Java tarball
get_url:
url: https://download.java.net/java/GA/jdk10/10.0.1/fb4372174a714e6b8c52526dc134031e/10/openjdk-10.0.1_linux-x64_bin.tar.gz
dest: /etc/open-jdk10.tar.gz
- name: make java 10 directory
file:
path: /usr/lib/java10
state: directory
Which uses ansible's get_url module to download the tarball and move it to the /etc/open-jdk10.tar.gz location, only downloading it if we haven't already done so. We then create the directory we eventually want to put java10 into
We can then convert:
# unpack tarball
tar -C /usr/lib/java10/ -xvzf ./openjdk-10.0.1_linux-x64_bin.tar.gz
Into:
- name: unpack tarball
unarchive:
dest: /usr/lib/java10
src: /etc/open-jdk10.tar.gz
remote_src: yes
This unpacks the tarball and places it into the directory previously created.
Finally, we will update alternatives (and, as a bonus, we'll set the JAVA_HOME environment variable):
- name: update alternatives for java
alternatives:
name: java
path: /usr/lib/java10/jdk-10.0.1/bin/java
link: /usr/bin/java
priority: 20000
- name: set java home as environment variable
blockinfile:
insertafter: EOF
path: /etc/environment
block: export JAVA_HOME=/usr/lib/java10/jdk-10.0.1
The final ansible playbook looks like:
---
- hosts: all
become: yes
gather_facts: no
pre_tasks:
- name: 'install python2 on ubuntu 18'
raw: test -e /usr/bin/python || (apt-get -y update && apt-get install -y python-minimal)
tasks:
- name: Gather facts
setup:
- name: Get Java tarball
get_url:
url: https://download.java.net/java/GA/jdk10/10.0.1/fb4372174a714e6b8c52526dc134031e/10/openjdk-10.0.1_linux-x64_bin.tar.gz
dest: /etc/open-jdk10.tar.gz
- name: make java 10 directory
file:
path: /usr/lib/java10
state: directory
- name: unpack tarball
unarchive:
dest: /usr/lib/java10
src: /etc/open-jdk10.tar.gz
remote_src: yes
- name: update alternatives for java
alternatives:
name: java
path: /usr/lib/java10/jdk-10.0.1/bin/java
link: /usr/bin/java
priority: 20000
- name: set java home as environment variable
blockinfile:
insertafter: EOF
path: /etc/environment
block: export JAVA_HOME=/usr/lib/java10/jdk-10.0.1
Nick Fisher is a software engineer in the Pacific Northwest. He focuses on building highly scalable and maintainable backend systems.