Configure Jenkins 2.0 with Ansible - jenkins

I am using Ansible for provision our servers, I installed the Jenkins 2.0 but it is becomeing with a startup configuration when I open the web UI. How can I do it with Ansible or shell or jenkins-cli. CentOS 7, Ansible 2.0.1.0.
So,
Installing Jenkins 2.0 from http://pkg.jenkins-ci.org/redhat-rc/jenkins-2.0-1.1.noarch.rpm rpm.
Install java with yum.
Service start jenkins.
Open 192.168.46.10:8080, which is opening the Jenkins.
In Web UI adding the initial admin password.
In web UI select and install plugins.
In web UI create a new admin user.
The 5,6,7 points are all the startup config of the new Jenkins. I haven't idea how we can install it autmatically.
Edit 1:
The 1,2,3 point is already done, just I didn't share because it is not necessary, because I only need an advice how can I configure the Jenkins. But now I add it to my question.
---
- name: Jenkins - install | Install java
yum: name=java state=installed
- name: Jenkins - install | Install Jenkins 2.0
yum: pkg=http://pkg.jenkins-ci.org/redhat-rc/jenkins-2.0-1.1.noarch.rpm state=installed
- name: Jenkins - install | Start and enable Jenkins 2.0
service: name=jenkins state=started enabled=yes

You can create an initialization script (in groovy) to add an admin account.
Script should be present in $JENKINS_HOME/init.groovy.d/*.groovy.
See Jenkins CI Wiki for more details.
Here's an example.
security.groovy.j2 file:
#!groovy
import java.util.logging.Level
import java.util.logging.Logger
import hudson.security.*
import jenkins.model.*
def instance = Jenkins.getInstance()
def logger = Logger.getLogger(Jenkins.class.getName())
logger.log(Level.INFO, "Ensuring that local user '{{ jenkins.admin_username }}' is created.")
if (!instance.isUseSecurity()) {
logger.log(Level.INFO, "Creating local admin user '{{ jenkins.admin_username }}'.")
def strategy = new FullControlOnceLoggedInAuthorizationStrategy()
strategy.setAllowAnonymousRead(false)
def hudsonRealm = new HudsonPrivateSecurityRealm(false)
hudsonRealm.createAccount("{{ jenkins.admin_username }}", "{{ jenkins.admin_password }}")
instance.setSecurityRealm(hudsonRealm)
instance.setAuthorizationStrategy(strategy)
instance.save()
}
How to use in Ansible playbook:
- name: Create initialization scripts directory
file: path={{ jenkins.home }}/init.groovy.d
state=directory
owner=jenkins
group=jenkins
mode=0775
- name: Add initialization script to setup basic security
template: src=security.groovy.j2
dest={{ jenkins.home }}/init.groovy.d/security.groovy
I was inspired by this GitHub reposiotry.

I found a solution, this is turn off the setup wizard, after it I was able to change config files.
- name: Jenkins - configure | Turn off Jenkins setup wizard
lineinfile: dest=/etc/sysconfig/jenkins regexp='^JENKINS_JAVA_OPTIONS=' line='JENKINS_JAVA_OPTIONS="-Djava.awt.headless=true -Djenkins.install.runSetupWizard=false"'
notify: restart jenkins

The above solution didn't work for me but give me hint and this is the solution that worked for me on Ubuntu:
- name: Configure JVM Arguments
lineinfile:
dest: /etc/default/jenkins
regexp: '^JAVA_ARGS='
line: 'JAVA_ARGS="-Djava.awt.headless=true -Djenkins.install.runSetupWizard=false"'
notify:
- Restart Jenkins

On Ubuntu 16.04 with Jenkins installed using apt-get, this works:
- name: "Turn off Jenkins setup wizard"
lineinfile:
dest: /etc/init.d/jenkins
regexp: '^JAVA_ARGS='
line: 'JAVA_ARGS="-Djava.awt.headless=true -Djenkins.install.runSetupWizard=false"'
insertbefore: '^DAEMON_ARGS='
notify: restart jenkins
- name: restart jenkins
service: name=jenkins state=restarted
You will still have to setup the security though!

Related

Configure Ansible playbook to skip Jenkins Initial setup

Hello I'm new to writing Ansible Playbooks but I'm trying to have my playbook install Jenkins. It installs Jenkins just fine but the issue becomes that it wants me to do the initial unlock before installing plugins, creating jobs etc. I've seen in here a few times people saying you just need to add this to your playbook and you should be good. When I add it and then run the playbook it still has this issue even if I do it from a brand new server. Wondering what everyone has done to get by this issue. Thanks for your assistance!
Code I've seen from other posts:
Gets error "Cannot get CSRF" when trying to install jenkins-plugin using ANSIBLE
- name: Jenkins Skip startUp for MI
lineinfile:
dest=/etc/sysconfig/jenkins
regexp='^JENKINS_JAVA_OPTIONS='
line='JENKINS_JAVA_OPTIONS="-Djava.awt.headless=true -Djenkins.install.runSetupWizard=false"'
register: result_skip_startup_wizard
My Playbook
---
# jenkins
- name: Create jenkins group
group:
name: jenkins
state: present
- name: Create jenkins user
user:
name: jenkins
group: jenkins
state: present
- name: Import jenkins gpg key
rpm_key:
state: present
key: http://pkg.jenkins.io/redhat-stable/jenkins.io.key
validate_certs: no
- name: Download Jenkins repo
get_url:
url: http://get.jenkins.io/redhat-stable/jenkins-2.332.3-1.1.noarch.rpm
dest: /etc/yum.repos.d/
- name: Install java
yum:
name: java-11-openjdk
state: present
- name: Install Jenkins
package:
name: /etc/yum.repos.d/jenkins-2.332.3-1.1.noarch.rpm
state: latest
- name: Jenkins Skip startUp for MI
lineinfile:
dest=/etc/sysconfig/jenkins
regexp='^JENKINS_JAVA_OPTIONS='
line='JENKINS_JAVA_OPTIONS="-Djava.awt.headless=true -Djenkins.install.runSetupWizard=false"'
register: result_skip_startup_wizard
- name: Start and Enable Jenkins
systemd:
name: jenkins
state: started
enabled: true
- name: Sleep for 30 seconds and continue with Jenkins buildout
wait_for: timeout=30
For reference this is what I see in the server when I check the file and then when I just grep for the process.
jenkins 8474 1 34 18:29 ? 00:00:20 /usr/bin/java -Djava.awt.headless=true -jar /usr/share/java/jenkins.war --webroot=/var/cache/jenkins/war --httpPort=8080
You can see the changes though do get put in the file as mentioned from above. Which makes me think even after restarting the service its not seeing the new option. I even manually stopped jenkins and then started but it still did not pick it up.
JENKINS_JAVA_OPTIONS="-Djava.awt.headless=true -Djenkins.install.runSetupWizard=false"
A little late here but I figured I'd leave a comment in here as well as I discovered when I was testing that the setup depended on the version of Jenkins you were attempting to install. Versions I tested are the comment lines above the code.
On the latest line it is just an assumption on my part not a guarantee.
# testing for jenkins 2.319.1
- name: Jenkins Skip startUp for MI
lineinfile:
dest=/etc/sysconfig/jenkins
regexp='^JENKINS_JAVA_OPTIONS='
line='JENKINS_JAVA_OPTIONS="-Djava.awt.headless=true -Djenkins.install.runSetupWizard=false"'
register: result_skip_startup_wizard
# below works for 2.332.1 or latest
- name: Jenkins Skip startUp for MI
lineinfile:
dest=/usr/lib/systemd/system/jenkins.service
regexp='^Environment="JAVA_OPTS=-Djava.awt.headless=true'
line='Environment="JAVA_OPTS=-Djava.awt.headless=true -Djenkins.install.runSetupWizard=false"'
register: result_skip_startup_wizard

Adding certificate to Jenkins configuation as code

I am configuring an installation of Jenkins through JCasC. One of the plugins we're using is Kubernetes.
In order to configure, it needs a server certificate to communicate with the k8s cluster.
This is how that part of the config looks like:
jenkins:
clouds:
-kubernetes:
name: "kubernetes"
serverUrl: "k8s URL"
serverCertificate: "serverCertificate"
skipTlsVerify: true
I am wondering how I can reference a file that contains the server certificate and put that file at the serverCertificate.
I would recommend you to rather use a predefined [jenkins] credentials:
and reference them inside JCasC pipeline as a way of accessing Kubernetes cluster.
jenkins:
clouds:
- kubernetes:
name: "advanced-k8s-config"
serverUrl: "https://avanced-k8s-config:443"
skipTlsVerify: true
namespace: "default"
credentialsId: "advanced-k8s-credentials"
jenkinsUrl: "http://jenkins/"
...
credentials:
system:
domainCredentials:
- credentials:
- fileSystemServiceAccountCredential:
id: "advanced-k8s-credentials"
Please check here for full code example.

Jenkins Slave Self Register

I am creating a Jenkins master/slave cluster and I am having trouble finding a way to have new slaves auto register themselves with the master.
My current set up is I run some Terraform scripts that will create the master and 5 slaves. Then I have to log in to the master node and Manage Jenkins -> Manage Nodes -> New Node and manually create the number of nodes I want.
Then I RDP into my slaves and run the command java -jar agent.jar -jnlpUrl http://yourserver:port/computer/agent-name/slave-agent.jnlp. This works perfectly fine, but I would like a way to auto scale up/down the number of agents without having to manually log into the slaves every time I create a new one.
Is there a plugin or some documentation I'm missing about how to dynamically self register nodes?
NOTE: This only applies to windows nodes. I am using the Kubernetes plugin to auto scale up/down linux nodes, but Kubernetes does not have stable windows nodes support so I can't use that. I have to support classic .NET applications (not .NET Core) so I have to build on windows nodes.
Here's a bash script I use on Linux, it could be adapted fairly easily for Windows.
#!/bin/bash
set -xe
MASTER_URL=$1
MASTER_USERNAME=$2
MASTER_PASSWORD=$3
NODE_NAME=$4
NUM_EXECUTORS=$5
# Download CLI jar from the master
curl ${MASTER_URL}/jnlpJars/jenkins-cli.jar -o ~/jenkins-cli.jar
# Create node according to parameters passed in
cat <<EOF | java -jar ~/jenkins-cli.jar -auth "${MASTER_USERNAME}:${MASTER_PASSWORD}" -s "${MASTER_URL}" create-node "${NODE_NAME}" |true
<slave>
<name>${NODE_NAME}</name>
<description></description>
<remoteFS>/home/jenkins/agent</remoteFS>
<numExecutors>${NUM_EXECUTORS}</numExecutors>
<mode>NORMAL</mode>
<retentionStrategy class="hudson.slaves.RetentionStrategy\$Always"/>
<launcher class="hudson.slaves.JNLPLauncher">
<workDirSettings>
<disabled>false</disabled>
<internalDir>remoting</internalDir>
<failIfWorkDirIsMissing>false</failIfWorkDirIsMissing>
</workDirSettings>
</launcher>
<label></label>
<nodeProperties/>
<userId>${USER}</userId>
</slave>
EOF
# Creating the node will fail if it already exists, so |true to suppress the
# error. This probably should check if the node exists first but it should be
# possible to see any startup errors if the node doesn't attach as expected.
# Run jnlp launcher
java -jar /usr/share/jenkins/slave.jar -jnlpUrl ${MASTER_URL}/computer/${NODE_NAME}/slave-agent.jnlp -jnlpCredentials "${MASTER_USERNAME}:${MASTER_PASSWORD}"
This is somewhat similar to the agent launchers included in the docker slave images, but before it runs jnlp it uses the jenkins cli to create the node on jenkins. Some of the parameters would need adapting to windows obviously.
EDIT: and to get that xml the easiest way is to create a node how you want in the web ui then use jenkins-cli to retrieve it.
I've been testing this on AWS.
https://plugins.jenkins.io/swarm
Although you cannot use broadcast on AWS you can add to the java command and specify the hostname or URL of the LB of the jenkins master.
I have not checked to see how this works on windows yet but will be doing that soon and will let you know how it goes.
I am using the Swarm Plugins https://plugins.jenkins.io/swarm to connect my Windows Clients to Jenkins.
At start-up I let my VMs running this Powershell Skript:
function startJenkinsSlave()
{
[CmdletBinding(SupportsShouldProcess=$true)]
param (
[parameter(Position = 1, Mandatory = $true)]
[string]$jkMasterUrl,
[parameter(Position = 2, Mandatory = $true)]
[string]$jkSlaveName,
[parameter(Position = 3, Mandatory = $true)]
[string]$jkSlaveUser,
[parameter(Position = 4, Mandatory = $true)]
[string]$jkSlaveSecret
)
Write-Host "--- start jenkins swarm slave ---"
Write-Host "download new Version of swarm-client.jar"
$jkSwarmJarUrl="$jkMasterUrl/swarm/swarm-client.jar"
$jkJarFilePath="C:\Program Files\Jenkins\swarm-client-$($jkSlaveName).jar"
$javaExePath="C:\ProgramData\Oracle\Java\javapath\java.exe"
Try {
[io.file]::OpenWrite($jkJarFilePath).close()
Get-ItemProperty -Path $jkJarFilePath -ErrorAction SilentlyContinue
$client = new-object System.Net.WebClient
$client.DownloadFile($jkSwarmJarUrl, $jkJarFilePath)
Write-Host "neueste Version vom swarm-client.jar wurde heruntergeladen"
Get-ItemProperty -Path $jkJarFilePath
}
Catch {
Write-Warning "Unable to write to output file $jkJarFilePath"
}
Write-Host "Jenkins slave will start:"
& $javaExePath '-Dfile.encoding=UTF8' -jar $jkJarFilePath -deleteExistingClients -master $jkMasterUrl -username $jkSlaveUser -password $jkSlaveSecret -labels "W10-swarm $jkSlaveName"
}
$jkSlaveUser='JenkinsUserForSwarm'
# Use access-token and not password!
$jkSlaveSecret='1d1a700e0a0981ef74f23efa9a6c90d39d'
$jkMasterUrl='http://jenkins.onmyhost.local:8080'
$vmName=(Get-ItemProperty -Path 'Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Virtual Machine\Guest\Parameters' -name 'VirtualMachineName').VirtualMachineName
Write-Host "Starting Jenkins Swarm"
while($true)
{
try
{
startJenkinsSlave -jkMasterUrl $jkMasterUrl -jkSlaveName $vmName -jkSlaveUser $jkSlaveUser -jkSlaveSecret $jkSlaveSecret
}
finally
{
# ctrl-c will the skript.
Write-Host "Jenkins Slave service ended. Restart in 120 seconds"
Start-Sleep -Seconds 120
}
}
This script works stabile and do the job for Windows slaves usefull when you need UI-iteractions.
You may also use env variable for the different parameters (jenkins master, user, token, ...).
For Unix slaves there may be better Solutions with k8s ans ssh.
Regards, Éric.

Jenkins job builder docker build and publish plugin issue

I am facing issue when Iam trying to build a Jenkins job using Jenkins job builder for docker build and publish plugin . I have 2 issues here :
1.) in repository tag it is not accepting "/" .
2.) registry url and password is not getting reflected in my jenkins job config (spacing is correct)
Here is my job template :
job-template:
name: '{name}_job'
description: 'Automatically generated test'
node: PROD-SLAVE
builders:
shell: |
BLAH BLAh
docker-build-publish:
repo-name: "npu-cluster/{name}"
repo-tag: 'BUILD_NUMBER'
no-cache: false
no-force-pull: false
skip-build: false
fingerprints: true
skip-decorate: false
skip-latest: true
skip-tag: false
file-path: '{name}/Dockerfile'
registry-url: url
registry-credentials-id: credentials-id
ssh-builder:
ssh-user-ip: centos#ip
command: blah blah
I found this question while searching solutions for the same kind of issue. Maybe you have found the answer already, but here's what worked for me anyway:
- docker-build-publish:
repo-name: 'sandboxname/component'
registry:
url: "https://yourremotelocation:port/"
credentials-id: "yourcredentialsid"

Sonar in Jenkins 2 Pipeline - missing global config

I try to run sonar tests with maven in my Jenkins pipeline project. The documentations says if the sonar is configured globally and you use the withSonarQube step the environment variables with the globally configured sonar properites are injected. So far so good.
http://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner+for+Jenkins#AnalyzingwithSonarQubeScannerforJenkins-AnalyzingwithSonarQubeScannerforMaven
My pipeline config looks like:
def stash = '********'
def branch = 'dev'
stage('git') {
node {
git branch: branch, credentialsId: 'Buildserver-Private.key', url: stash
}
}
stage('build') {
node {
//....
}
}
stage('sonar') {
node {
withSonarQubeEnv('Sonar') {
sh 'mvn org.sonarsource.scanner.maven:sonar-maven-plugin:3.2:sonar'
}
}
}
The build fails because the sonar plugin trys to connect to the default h2 database instead of the configured one. If i check the log, there are no sonar properties passed to maven.
Injecting SonarQube environment variables using the configuration: Sonar
[Pipeline] {
[Pipeline] tool
[Pipeline] sh
[***********] Running shell script
+ cd .
+ /var/lib/jenkins/tools/hudson.tasks.Maven_MavenInstallation/Maven_3_3_9/bin/mvn org.sonarsource.scanner.maven:sonar-maven-plugin:3.2:sonar
[INFO] Scanning for projects...
[...]
[INFO] --- sonar-maven-plugin:3.2:sonar (default-cli) # *******.project.build ---
[INFO] User cache: /var/lib/jenkins/.sonar/cache
[INFO] SonarQube version: 4.5.6
[INFO] Default locale: "en_US", source code encoding: "UTF-8" (analysis is platform dependent)
12:23:17.971 INFO - Load global referentials...
12:23:18.071 INFO - Load global referentials done: 102 ms
12:23:18.102 INFO - User cache: /var/lib/jenkins/.sonar/cache
12:23:18.109 INFO - Install plugins
12:23:18.176 INFO - Install JDBC driver
12:23:18.183 INFO - Create JDBC datasource for jdbc:h2:tcp://localhost/sonar
Why is my config ignored? What does the documentation mean if it says?
Since version 2.5 of the SonarQube Scanner for Jenkins, there is an
official support of Jenkins pipeline. We provide a 'withSonarQubeEnv'
block that allow to select the SonarQube server you want to interact
with. Connection details you have configured in Jenkins global
configuration will be automatically passed to the scanner.
It seems they are not ...
Has anybody an idea what am I missing?
You are using an old version of SonarQube (4.5.6, the previous LTS) that requires to pass DB connection parameters (URL, login, password) to the scanners - which is a security issue. withSonarQubeEnv does not propagate those settings in order to fix this flaw.
Since SonarQube 5.2, these parameters are no longer required. So you have to use a version that is more recent. I suggest you to upgrade to the latest LTS version of SonarQube (5.6).

Resources