1
0
Fork 0

First commit

This commit is contained in:
Chl 2020-01-17 23:35:15 +01:00
commit e54b5a5663
24 changed files with 3047 additions and 0 deletions

View file

@ -0,0 +1,24 @@
---
# Etckeeper is a small fondness of mine, it semi-automatically
# keep track of /etc with git.
# Feel free to remove all this if you'rs not interested.
- name: detect etckeeper presence
shell: "which etckeeper"
ignore_errors: True
register: tmp
changed_when: False
- name: Set fact about etckeeper presence
set_fact:
etckeeper_installed: "{{ tmp.rc == 0 }}"
- name: Check that /etc is clean
shell: etckeeper unclean && echo "Uncommitted changes." && return 1 || return 0
ignore_errors: True # we add a 'fail' task to tell the problem more explictly.
register: tmp
changed_when: False
when: etckeeper_installed
- fail:
msg: "Etckeeper is installed but there is uncommitted changes in /etc."
when: etckeeper_installed and tmp.rc != 0

View file

@ -0,0 +1,65 @@
---
# Add Jenkins repository for Debian
- name: Add Jenkins-stable.io repository key
apt_key:
id: "150FDE3F7787E7D11EF4E12A9B7D32F2D50582E6"
data: "{{ lookup('file', 'jenkins-stable.io.pem') }}"
state: present
register: tmp
- name: New APT sources - commit
command: "etckeeper commit 'apt: Jenkins repository key added by Ansible'"
when: tmp.changed and etckeeper_installed
- name: Check if /etc/apt/sources.list.d/jenkins.list is managed by ansible
shell: "grep -ic '# This file is managed by Ansible' /etc/apt/sources.list.d/jenkins.list || true"
register: result
changed_when: false
- name: Config /etc/apt/sources.list.d/jenkins.list file
template:
src: "{{ item }}"
dest: /etc/apt/sources.list.d/jenkins.list
owner: root
group: root
mode: 0644
backup: no
force: "{{ result.stdout is defined and result.stdout == '1' }}" # Only manage the file if the header is present
with_first_found:
- "jenkins.list.{{ ansible_fqdn }}.j2"
- "jenkins.list.j2"
register: tmp
- name: New APT sources - commit
command: "etckeeper commit 'apt: Jenkins repository added/changed by Ansible'"
when: tmp.changed and etckeeper_installed
- name: Update APT cache
apt:
update_cache: yes
when: tmp.changed
# Install Jenkins
# (note: the Jenkins package doesn't wait for Java to be installed
# before trying to launch itself, so we install them separately)
# (note2: in case we go back downloading the .war, here is a command to
# verify it: jarsigner -verbose -certs -verify /tmp/jenkins.war
- name: Install Java
apt:
name:
- default-jdk
state: present
- name: Install Jenkins package
apt:
name:
- jenkins
state: present
register: result
- name: Loop until Jenkins is available
get_url:
url: "http://localhost:8080/login"
dest: "/dev/null"
force: True
register: tmp
until: tmp.status_code is defined and tmp.status_code == 200 or result.changed == False
retries: 10
delay: 5
changed_when: False

View file

@ -0,0 +1,50 @@
---
# Install plugins
# inspired by https://github.com/geerlingguy/ansible-role-jenkins MIT (Expat) / BSD)
# but we couldn't use jenkins_plugin's Ansible module because of crumb (CSRF) problems with our version
# Get current plugin list
# Warning : it may not be up to date if Jenkins hasn't been restarted after last plugin install
- name: Get the current plugin list
shell: "{{ jenkins_cli_command }} list-plugins | awk '{ print $1 }'"
changed_when: False
check_mode: no
register: current_plugin_list
## Update Jenkins so that plugin updates don't fail.
#- name: Create Jenkins updates directory.
# file:
# path: "{{ jenkins_home }}/updates"
# state: directory
# owner: jenkins
# group: jenkins
#
#- name: Download current plugin updates from Jenkins update site.
# get_url:
# url: "{{ jenkins_updates_url }}/update-center.json"
# dest: "{{ jenkins_home }}/updates/default.json"
# owner: jenkins
# group: jenkins
# mode: 0440
# changed_when: false
# register: get_result
# until: get_result is success
# retries: 3
# delay: 2
#
#- name: Remove first and last line from json file.
# replace:
# path: "{{ jenkins_home }}/updates/default.json"
# regexp: "1d;$d"
- name: Install Jenkins plugins.
shell: "{{ jenkins_cli_command }} install-plugin {{ item | quote }}"
with_items: "{{ jenkins_plugins }}"
when: item not in current_plugin_list.stdout_lines
notify: safe-restart jenkins and wait
- name: Install system package needed by Jenkins plugins
apt:
name: "{{ jenkins_plugins_system_dependency }}"
state: present

View file

@ -0,0 +1,29 @@
---
- name: Check if Gitea user has already been created
stat:
path: "{{ jenkins_gitea_password_file }}"
register: result
- name: Do we have to create the Gitea user
set_fact:
createGiteaUser: "{{ result.stat.exists is undefined or result.stat.exists == False }}"
- name: Generate a password for the Gitea user
set_fact:
giteaPassword: "{{ lookup('password', '/dev/null chars=ascii_letters') }}"
when: createGiteaUser
- name: Create Gitea user
shell: echo 'jenkins.model.Jenkins.instance.securityRealm.createAccount("gitea", "{{ giteaPassword | quote }}")' | "{{ jenkins_cli_command }}" groovy =
when: createGiteaUser
- name: Upload the new password
copy:
content: "{{ giteaPassword }}"
dest: "{{ jenkins_gitea_password_file }}"
owner: jenkins
group: jenkins
mode: 0600
when: createGiteaUser
#no_log: yes # FIXME: actually, we want to know it to tell the user to set a URL with it in Gitea. Add a debug msg maybe ?

View file

@ -0,0 +1,85 @@
---
# Needed to write a config.xml which is not changed at each Ansible run
- name: Get current Jenkins version
shell: "{{ jenkins_cli_command }} version"
changed_when: False
check_mode: no
register: result
- name: Set fact about current Jenkins version
set_fact:
current_jenkins_version: "{{ result.stdout_lines[0] }}"
- name: Upload main config.xml
template:
src: "{{ item }}"
dest: "{{ jenkins_home }}/config.xml"
owner: jenkins
group: jenkins
mode: 0644
backup: yes
with_first_found:
- "config.xml.{{ ansible_fqdn }}.j2"
- "config.xml.j2"
notify: safe-restart jenkins and wait
- name: Upload JenkinsLocationConfiguration.xml
template:
src: "{{ item }}"
dest: "{{ jenkins_home }}/jenkins.model.JenkinsLocationConfiguration.xml"
owner: jenkins
group: jenkins
mode: 0644
backup: yes
with_first_found:
- "jenkins.model.JenkinsLocationConfiguration.xml.{{ ansible_fqdn }}.j2"
- "jenkins.model.JenkinsLocationConfiguration.xml.j2"
notify: safe-restart jenkins and wait
# Generate a SSH RSA key pair if not already present
# (we do it without the Ansible module which is only available starting 2.8)
# (and we don't use become/become_user because it fails with a permission denied on /tmp/.ansible...)
- name: Generate SSH RSA key pair
command: su -c 'ssh-keygen -q -t rsa -b 2048 -f ~/.ssh/id_rsa -N ""' - jenkins
args:
creates: "{{ jenkins_home }}/.ssh/id_rsa"
#become_user: jenkins # permission denied
#become: yes
register: result
- name: Retrieve the SSH private key
slurp:
src: "{{ jenkins_home }}/.ssh/id_rsa.pub"
register: tmp
when: result.changed
- name: Ouput public key
debug:
msg: "Don't forget to set the public key on the Git repository and the deploy target : {{ tmp.content | b64decode | trim }}"
when: result.changed
# Upload this new key to the Jenkins credentials plugin system
# (the create/update/import-credential-as-xml is kinda cumbersome for our
# usecase. No way to export the key or get a MD5/SHA256 of it, so we just
# go for the credentials.xml file directly :)
- name: Retrieve the SSH private key
slurp:
src: "{{ jenkins_home }}/.ssh/id_rsa"
register: tmp
no_log: yes
- name: Set fact about SSH key
set_fact:
ssh_private_key: "{{ tmp.content | b64decode | trim }}"
no_log: yes
- name: Upload SSH RSA key pair as credential in Jenkins
template:
src: "{{ item }}"
dest: "{{ jenkins_home }}/credentials.xml"
owner: jenkins
group: jenkins
mode: 0600
force: yes
backup: yes
with_first_found:
- "credentials.xml.{{ ansible_fqdn }}.j2"
- "credentials.xml.j2"
notify: safe-restart jenkins and wait
#shell: cat /tmp/tmp.xml | java -jar /var/cache/jenkins/war/WEB-INF/jenkins-cli.jar -s http://localhost:8080/ -auth admin:$( cat /var/lib/jenkins/secrets/initialAdminPassword ) create-credentials-by-xml system::system::jenkins _

View file

@ -0,0 +1,18 @@
---
# We need Jenkins to reboot if new plugins were installed.
- meta: flush_handlers
- name: Get the list of jobs that already exist
shell: "{{ jenkins_cli_command }} list-jobs"
changed_when: False
check_mode: no
register: current_jobs_list
# Loop on every job we maintain
- name: Manage each job
include_tasks:
file: include_jobinstall.yml
loop: "{{ lookup('dict', jobs ) }}"
loop_control:
loop_var: job

View file

@ -0,0 +1,28 @@
---
# When the job doesn't exist, we provide an empty XML, and then work
# directly on the jenkins_home/jobs/JOB/config.xml file
- name: Create a empty job
shell: "echo '<project />' | {{ jenkins_cli_command }} create-job {{ job.key | quote }}"
when: job.key not in current_jobs_list.stdout_lines
- name: Upload job config template
template:
src: "{{ item }}"
# if job exists, we write directly to jobs/JOBNAME/config.xml, else we write to the tmp file.
dest: "{{ jenkins_home + '/jobs/' + job.key + '/config.xml' }}"
mode: 0600
owner: jenkins
group: jenkins
backup: yes
force: yes
with_first_found:
- "jobs/config.xml.{{ ansible_fqdn }}.{{ job.key }}.j2"
- "jobs/config.xml.{{ job.key }}.j2"
- "jobs/config.xml.{{ ansible_fqdn }}.j2"
- "jobs/config.xml.j2"
register: jobconfig
- name: Reload the job
shell: "{{ jenkins_cli_command }} reload-job {{ job.key | quote }}"
when: jobconfig.changed

View file

@ -0,0 +1,16 @@
---
- name: safe-restart jenkins and wait (include)
block:
- name: safe-restart jenkins
shell: "{{ jenkins_cli_command }} safe-restart"
- name: Loop until Jenkins is available
get_url:
url: "http://localhost:8080/login"
dest: "/dev/null"
force: True
register: result
until: result.status_code is defined and result.status_code == 200
retries: 10
delay: 5
changed_when: False

View file

@ -0,0 +1,41 @@
---
# Usually, we only install Jenkins and let it live its life,
# so if it seems to be already installed, we skip this task.
- name: Check if /var/lib/jenkins exists
stat:
path: "{{ jenkins_home }}"
register: result
- name: No going further if jenkinsonlyinstall is set and Jenkins is already installed
set_fact:
gogogo: "{{ jenkins_installonly is undefined or jenkins_installonly == False or result.stat.isdir is undefined or result.stat.isdir == False }}"
- name: Warning about confidentiality
pause:
prompt: "Warning: this role will manage and display a lot of passwords and keys readable through the Ansible log and the process infos on each host. Sorry..."
seconds: 1 # TODO: 10
when: gogogo
# Pre-check
- include_tasks: roles/jenkins-php-v1/tasks/00_precheck.yml
when: gogogo
# Install Jenkins via the upstream repository
- include_tasks: roles/jenkins-php-v1/tasks/10_jenkins-repository.yml
when: gogogo
- include_tasks: roles/jenkins-php-v1/tasks/20_install-plugins.yml
when: gogogo
# At the moment, groups or roles are kinda overkill
# (but it probably will get back on us at the end...)
- include_tasks: roles/jenkins-php-v1/tasks/30_users.yml
when: gogogo
# Big configuration step : ACL, SSH keys aka. credentials, etc.
- include_tasks: roles/jenkins-php-v1/tasks/40_configure-jenkins.yml
when: gogogo
- include_tasks: roles/jenkins-php-v1/tasks/50_create-jobs.yml
when: gogogo