Example: Jenkins CI Server
Jenkins CI Server
Provision a Jenkins CI/CD server with Java runtime, plugin management, and build agent configuration.
Directory Structure
cookbooks/
jenkins/
default.rb
templates/
jenkins-defaults.erb
jenkins-nginx.conf.erb
nodes/
ci01.json
Node Attributes
{
"jenkins": {
"http_port": 8080,
"home_dir": "/var/lib/jenkins",
"java_version": "17",
"memory_max": "2g",
"memory_min": "512m",
"admin_user": "admin",
"agent_port": 50000,
"proxy_server_name": "ci.example.com",
"executors": 4,
"plugins": ["git", "pipeline", "docker-workflow", "blueocean"]
}
}
Recipe
# cookbooks/jenkins/default.rb
jen = node['jenkins']
# --- Java Runtime ---
package "openjdk-#{jen['java_version']}-jdk-headless" do
action :install
end
# --- Jenkins Repository ---
execute 'add-jenkins-key' do
command 'curl -fsSL https://pkg.jenkins.io/debian-stable/jenkins.io-2023.key | tee /usr/share/keyrings/jenkins-keyring.asc > /dev/null'
not_if 'test -f /usr/share/keyrings/jenkins-keyring.asc'
end
execute 'add-jenkins-repo' do
command 'echo "deb [signed-by=/usr/share/keyrings/jenkins-keyring.asc] https://pkg.jenkins.io/debian-stable binary/" > /etc/apt/sources.list.d/jenkins.list'
not_if 'test -f /etc/apt/sources.list.d/jenkins.list'
end
execute 'apt-update-jenkins' do
command 'apt-get update'
end
package 'jenkins' do
action :install
end
# --- Jenkins directories ---
directory jen['home_dir'] do
owner 'jenkins'
group 'jenkins'
mode '0755'
end
directory "#{jen['home_dir']}/plugins" do
owner 'jenkins'
group 'jenkins'
mode '0755'
end
directory '/var/log/jenkins' do
owner 'jenkins'
group 'jenkins'
mode '0750'
end
# --- JVM and Jenkins defaults ---
template '/etc/default/jenkins' do
source 'templates/jenkins-defaults.erb'
owner 'root'
group 'root'
mode '0644'
variables(
http_port: jen['http_port'],
home_dir: jen['home_dir'],
memory_max: jen['memory_max'],
memory_min: jen['memory_min'],
agent_port: jen['agent_port']
)
notifies :restart, 'service[jenkins]'
end
# --- Install plugins via CLI ---
jen['plugins'].each do |plugin|
execute "install-plugin-#{plugin}" do
command "java -jar #{jen['home_dir']}/war/WEB-INF/jenkins-cli.jar -s http://localhost:#{jen['http_port']}/ install-plugin #{plugin}"
not_if "test -d #{jen['home_dir']}/plugins/#{plugin}"
end
end
# --- Nginx reverse proxy ---
package 'nginx' do
action :install
end
template '/etc/nginx/sites-available/jenkins' do
source 'templates/jenkins-nginx.conf.erb'
owner 'root'
group 'root'
mode '0644'
variables(
server_name: jen['proxy_server_name'],
http_port: jen['http_port']
)
notifies :reload, 'service[nginx]'
end
link '/etc/nginx/sites-enabled/jenkins' do
to '/etc/nginx/sites-available/jenkins'
notifies :reload, 'service[nginx]'
end
service 'jenkins' do
action [:enable, :start]
end
service 'nginx' do
action [:enable, :start]
end
Templates
jenkins-defaults.erb
JENKINS_HOME="<%= @home_dir %>"
JENKINS_PORT="<%= @http_port %>"
JENKINS_ARGS="--httpPort=<%= @http_port %>"
JAVA_ARGS="-Xms<%= @memory_min %> -Xmx<%= @memory_max %> -Djava.awt.headless=true -Dhudson.model.DirectoryBrowserSupport.CSP= -Djenkins.model.Jenkins.slaveAgentPort=<%= @agent_port %>"
jenkins-nginx.conf.erb
upstream jenkins {
server 127.0.0.1:<%= @http_port %>;
keepalive 32;
}
server {
listen 80;
server_name <%= @server_name %>;
location / {
proxy_pass http://jenkins;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 90;
}
}
Running
itamae ssh -j nodes/ci01.json -h ci01.example.com cookbooks/jenkins/default.rb