Table of Contents
Overview
This guide provides detailed instructions for installing and configuring Ansible and Java 8 on Ubuntu 20.04. Whether you’re setting up a development environment or preparing for automation tasks, this guide covers everything from basic installation to advanced configuration.
System Architecture
graph TB subgraph "Control Node" A[Ansible Control Node] B[Java 8 Runtime] C[SSH Keys] end
subgraph "Managed Nodes" D[Node 1] E[Node 2] F[Node N] end
subgraph "Configuration" G[Inventory File] H[Playbooks] I[Variables] end
A --> D A --> E A --> F A --> G G --> H H --> I C --> D C --> E C --> F
style A fill:#4ecdc4,stroke:#087f5b,stroke-width:2px style B fill:#ffd43b,stroke:#fab005,stroke-width:2px style G fill:#74c0fc,stroke:#1971c2,stroke-width:2pxPrerequisites
Before proceeding, ensure you have:
- Ubuntu 20.04 LTS system (physical or virtual)
- Root or sudo access
- Internet connection for package downloads
- At least 2GB RAM and 10GB disk space
- Basic understanding of Linux command line
Installing Ansible
Step 1: Update System Packages
# Update package indexsudo apt update
# Upgrade existing packagessudo apt upgrade -y
# Install software properties commonsudo apt install -y software-properties-commonStep 2: Add Ansible Repository
# Add official Ansible PPAsudo apt-add-repository ppa:ansible/ansible
# Update package index againsudo apt updateStep 3: Install Ansible
# Install Ansiblesudo apt install -y ansible
# Verify installationansible --version
# Check Python version (Ansible requires Python)python3 --versionStep 4: Configure Ansible User
# Create dedicated Ansible usersudo useradd -m ansiblesudo passwd ansible
# Add to sudo groupsudo usermod -aG sudo ansible
# Configure sudoers for passwordless sudoecho "ansible ALL=(ALL) NOPASSWD: ALL" | sudo tee /etc/sudoers.d/ansibleSetting Up SSH Keys
Generate SSH Keys
# Switch to ansible usersudo su - ansible
# Generate SSH key pairssh-keygen -t rsa -b 4096 -C "ansible@control-node"
# View public keycat ~/.ssh/id_rsa.pubDistribute SSH Keys to Managed Nodes
# Copy SSH key to managed nodesssh-copy-id ansible@managed-node-ip
# Test SSH connectionssh ansible@managed-node-ip
# For multiple nodes, use a loopfor host in node1 node2 node3; do ssh-copy-id ansible@$hostdoneConfiguring Ansible Inventory
Edit Inventory File
# Create custom inventory directorysudo mkdir -p /etc/ansible/inventories/production
# Edit inventory filesudo nano /etc/ansible/inventories/production/hostsAdd the following content:
[web_servers]web1 ansible_host=192.168.1.10 ansible_user=ansibleweb2 ansible_host=192.168.1.11 ansible_user=ansible
[db_servers]db1 ansible_host=192.168.1.20 ansible_user=ansibledb2 ansible_host=192.168.1.21 ansible_user=ansible
[all:vars]ansible_python_interpreter=/usr/bin/python3ansible_ssh_common_args='-o StrictHostKeyChecking=no'
[web_servers:vars]http_port=80max_clients=200
[db_servers:vars]mysql_port=3306max_connections=100Ansible Configuration File
Create or edit /etc/ansible/ansible.cfg:
[defaults]inventory = /etc/ansible/inventories/production/hostsremote_user = ansiblehost_key_checking = Falseretry_files_enabled = Falsegathering = smartfact_caching = jsonfilefact_caching_connection = /tmp/ansible_facts_cachefact_caching_timeout = 86400
[privilege_escalation]become = Truebecome_method = sudobecome_user = rootbecome_ask_pass = False
[ssh_connection]ssh_args = -C -o ControlMaster=auto -o ControlPersist=60spipelining = TrueInstalling Java 8
Step 1: Install OpenJDK 8
# Update package indexsudo apt update
# Install OpenJDK 8 JDK (includes JRE)sudo apt install -y openjdk-8-jdk
# Verify installationjava -versionjavac -versionStep 2: Configure Java Environment
# Set JAVA_HOME environment variableecho 'export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64' >> ~/.bashrcecho 'export PATH=$PATH:$JAVA_HOME/bin' >> ~/.bashrc
# Reload bashrcsource ~/.bashrc
# Verify environment variablesecho $JAVA_HOMEStep 3: Manage Multiple Java Versions
# Check all installed Java versionssudo update-alternatives --list java
# Configure default Java versionsudo update-alternatives --config java
# Configure default javac versionsudo update-alternatives --config javacTesting the Installation
Test Ansible Connection
# Ping all hostsansible all -m ping
# Ping specific groupansible web_servers -m ping
# Run ad-hoc commandansible all -a "uname -a"
# Check disk space on all hostsansible all -m shell -a "df -h"Create Test Playbook
Create test-playbook.yml:
---- name: Test Playbook hosts: all gather_facts: yes tasks: - name: Display system information debug: msg: "{{ ansible_hostname }} - {{ ansible_distribution }} {{ ansible_distribution_version }}"
- name: Check Java installation command: java -version register: java_version ignore_errors: yes
- name: Display Java version debug: msg: "Java is installed: {{ java_version.stderr }}" when: java_version.rc == 0
- name: Ensure Apache is installed (web servers only) apt: name: apache2 state: present when: inventory_hostname in groups['web_servers']Run the playbook:
# Run playbookansible-playbook test-playbook.yml
# Run with verbose outputansible-playbook -vvv test-playbook.yml
# Run with check mode (dry run)ansible-playbook --check test-playbook.ymlTest Java Installation
Create HelloWorld.java:
public class HelloWorld { public static void main(String[] args) { System.out.println("Hello from Java " + System.getProperty("java.version")); System.out.println("Running on " + System.getProperty("os.name")); }}Compile and run:
# Compilejavac HelloWorld.java
# Runjava HelloWorldAdvanced Configuration
Ansible Vault for Secrets
# Create encrypted variables fileansible-vault create group_vars/all/vault.yml
# Edit encrypted fileansible-vault edit group_vars/all/vault.yml
# Use in playbookansible-playbook playbook.yml --ask-vault-passDynamic Inventory Script
Create dynamic_inventory.py:
#!/usr/bin/env python3import jsonimport argparse
def get_inventory(): inventory = { 'web_servers': { 'hosts': ['web1', 'web2'], 'vars': { 'http_port': 80 } }, '_meta': { 'hostvars': { 'web1': { 'ansible_host': '192.168.1.10' }, 'web2': { 'ansible_host': '192.168.1.11' } } } } return inventory
if __name__ == '__main__': parser = argparse.ArgumentParser() parser.add_argument('--list', action='store_true') parser.add_argument('--host', action='store') args = parser.parse_args()
if args.list: print(json.dumps(get_inventory())) elif args.host: print(json.dumps({}))Make it executable and test:
chmod +x dynamic_inventory.pyansible -i dynamic_inventory.py all -m pingSecurity Best Practices
SSH Security
# Configure SSH daemonsudo nano /etc/ssh/sshd_config
# Recommended settings:PermitRootLogin noPasswordAuthentication noPubkeyAuthentication yesAllowUsers ansibleAnsible Security
graph TD A[Security Measures] --> B[SSH Keys] A --> C[Ansible Vault] A --> D[Limited Sudo] A --> E[Network Segmentation]
B --> F[4096-bit RSA] B --> G[Passphrase Protected]
C --> H[Encrypted Passwords] C --> I[Encrypted Variables]
D --> J[Specific Commands] D --> K[No Password Required]
E --> L[Firewall Rules] E --> M[VPN Access]
style A fill:#ff6b6b,stroke:#c92a2a,stroke-width:2px style B fill:#74c0fc,stroke:#1971c2,stroke-width:2px style C fill:#74c0fc,stroke:#1971c2,stroke-width:2pxTroubleshooting
Common Issues and Solutions
-
SSH Connection Refused
Terminal window # Check SSH servicesudo systemctl status ssh# Check firewallsudo ufw status -
Python Interpreter Not Found
Terminal window # Install Python on managed nodeansible node -m raw -a "apt update && apt install -y python3" -
Java Command Not Found
Terminal window # Update alternativessudo update-alternatives --install /usr/bin/java java /usr/lib/jvm/java-8-openjdk-amd64/bin/java 1
Debug Commands
# Verbose Ansible outputansible-playbook playbook.yml -vvvv
# Check Ansible configurationansible-config dump
# List all factsansible hostname -m setupPerformance Optimization
Ansible Performance Tips
# ansible.cfg optimizations[defaults]forks = 20poll_interval = 15strategy = freegathering = smartfact_caching = jsonfilefact_caching_connection = /tmpfact_caching_timeout = 86400
[ssh_connection]pipelining = Truecontrol_path = /tmp/ansible-%%h-%%p-%%rJava Performance Tuning
# Set Java heap sizeexport JAVA_OPTS="-Xms512m -Xmx2048m"
# Enable G1 garbage collectorexport JAVA_OPTS="$JAVA_OPTS -XX:+UseG1GC"Monitoring and Maintenance
Monitoring Script
#!/bin/bashecho "=== Ansible Status ==="ansible --version
echo -e "\n=== Reachable Hosts ==="ansible all -m ping --one-line
echo -e "\n=== Java Version on Hosts ==="ansible all -m shell -a "java -version 2>&1 | head -1" --one-line
echo -e "\n=== System Resources ==="ansible all -m shell -a "free -h && df -h /" --one-lineConclusion
You now have a fully configured Ubuntu 20.04 system with Ansible and Java 8 installed. This setup provides:
- Ansible automation capabilities for managing multiple nodes
- Java 8 runtime for Java-based applications
- Secure SSH connectivity between control and managed nodes
- Optimized configuration for performance and security
Key takeaways:
- Always use SSH keys for authentication
- Keep your Ansible playbooks in version control
- Use Ansible Vault for sensitive data
- Regularly update both Ansible and Java
- Monitor your managed nodes for consistency
This foundation enables you to automate infrastructure management, deploy applications, and maintain consistent environments across your systems.