diff --git a/inventory.yml b/inventory.yml index 08348b2..1a6faab 100644 --- a/inventory.yml +++ b/inventory.yml @@ -19,3 +19,6 @@ all: # Check if etckeeper is installed and /etc is clean checketckeeper: True + + # admin email address + jenkins_admin_email: postmaster@example.net diff --git a/roles/jenkins-php-v1/defaults/main.yml b/roles/jenkins-php-v1/defaults/main.yml index dc6b879..310b17c 100644 --- a/roles/jenkins-php-v1/defaults/main.yml +++ b/roles/jenkins-php-v1/defaults/main.yml @@ -13,6 +13,14 @@ jenkins_credential_keydesc: Deploy key n.1 # Default branch for git clone/pull in the job configuration branch_spec: "*/master" +# Nginx/Jenkins configuration +nginx_vhost_main_hostname: "{{ ansible_fqdn }}" +nginx_vhost_resource_hostname: "resource.{{ ansible_fqdn }}" +nginx_vhost_ssl_certificate_file: "/etc/nginx/ssl/{{ nginx_vhost_main_hostname }}.crt" +nginx_vhost_ssl_key_file: "/etc/nginx/ssl/{{ nginx_vhost_main_hostname }}.key" +# null means "whether nginx_vhost_ssl_certificate_file exists on remote host" +nginx_vhost_ssl: + jenkins_plugins: - credentials - git-client diff --git a/roles/jenkins-php-v1/handlers/main.yml b/roles/jenkins-php-v1/handlers/main.yml index 99bdd90..ed98147 100644 --- a/roles/jenkins-php-v1/handlers/main.yml +++ b/roles/jenkins-php-v1/handlers/main.yml @@ -9,3 +9,6 @@ # As of now (Ansible 2.7.7), Ansible doesn't support blocks in handlers - name: safe-restart jenkins and wait import_tasks: roles/jenkins-php-v1/tasks/include_saferestartandwait.yml + +- name: reload nginx + service: name=nginx state=reloaded diff --git a/roles/jenkins-php-v1/tasks/00_precheck.yml b/roles/jenkins-php-v1/tasks/00_precheck.yml index e9cdb1d..ed31188 100644 --- a/roles/jenkins-php-v1/tasks/00_precheck.yml +++ b/roles/jenkins-php-v1/tasks/00_precheck.yml @@ -18,3 +18,14 @@ shell: etckeeper unclean && echo "Uncommitted changes." && return 1 || return 0 changed_when: False when: etckeeper_installed + +# Autodetect if we can use HTTPS in Nginx and jenkinsUrl configs +- name: Autodetect SSL - look up certificate existence on remote host + stat: + path: "{{ nginx_vhost_ssl_certificate_file }}" + register: result + when: nginx_vhost_ssl is undefined or nginx_vhost_ssl == None +- name: Autodetect SSL - set fact + set_fact: + nginx_vhost_ssl: "{{ result.stat.exists is defined and result.stat.exists }}" + when: nginx_vhost_ssl is undefined or nginx_vhost_ssl == None diff --git a/roles/jenkins-php-v1/tasks/40_configure-jenkins.yml b/roles/jenkins-php-v1/tasks/40_configure-jenkins.yml index 5e63a34..e6eddb8 100644 --- a/roles/jenkins-php-v1/tasks/40_configure-jenkins.yml +++ b/roles/jenkins-php-v1/tasks/40_configure-jenkins.yml @@ -36,6 +36,19 @@ - "jenkins.model.JenkinsLocationConfiguration.xml.j2" notify: safe-restart jenkins and wait +- name: Upload ResourceDomainConfiguration.xml + template: + src: "{{ item }}" + dest: "{{ jenkins_home }}/jenkins.security.ResourceDomainConfiguration.xml" + owner: jenkins + group: jenkins + mode: 0644 + backup: yes + with_first_found: + - "jenkins.security.ResourceDomainConfiguration.xml.{{ ansible_fqdn }}.j2" + - "jenkins.security.ResourceDomainConfiguration.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...) diff --git a/roles/jenkins-php-v1/tasks/60_install-nginx-proxy.yml b/roles/jenkins-php-v1/tasks/60_install-nginx-proxy.yml new file mode 100644 index 0000000..c066176 --- /dev/null +++ b/roles/jenkins-php-v1/tasks/60_install-nginx-proxy.yml @@ -0,0 +1,49 @@ +--- + + +- name: Install NginX + apt: + name: + - nginx-light + state: present + +- name: Upload the nginx vhosts template + template: + src: "{{ item }}" + dest: /etc/nginx/sites-available/jenkins + owner: root + group: root + backup: yes + force: yes + with_first_found: + - "nginx-vhost.{{ ansible_fqdn }}.j2" + - "nginx-vhost.j2" + register: tmp + notify: reload nginx +- name: Etckeeper - commit + command: "etckeeper commit 'Ansible/nginx: maintaining Jenkins vhost'" + when: tmp.changed and etckeeper_installed + +- name: Activate nginx vhost + file: + src: /etc/nginx/sites-available/jenkins + dest: /etc/nginx/sites-enabled/jenkins + state: link + register: tmp + notify: reload nginx +- name: Etckeeper - commit + command: "etckeeper commit 'Ansible/nginx: activating Jenkins vhost'" + when: tmp.changed and etckeeper_installed + +- name: Make Jenkins only listen to loopback network interface + ini_file: + path: /etc/default/jenkins + section: + option: JENKINS_ARGS + value: '"--webroot=/var/cache/$NAME/war --httpPort=$HTTP_PORT --httpListenAddress=127.0.0.1"' + no_extra_spaces: yes + register: tmp + notify: restart jenkins +- name: Etckeeper - commit + command: "etckeeper commit 'Ansible/jenkins: maintaining /etc/default/jenkins'" + when: tmp.changed and etckeeper_installed diff --git a/roles/jenkins-php-v1/tasks/main.yml b/roles/jenkins-php-v1/tasks/main.yml index fe69c43..a9b4118 100644 --- a/roles/jenkins-php-v1/tasks/main.yml +++ b/roles/jenkins-php-v1/tasks/main.yml @@ -39,3 +39,6 @@ - include_tasks: roles/jenkins-php-v1/tasks/50_create-jobs.yml when: gogogo + +- include_tasks: roles/jenkins-php-v1/tasks/60_install-nginx-proxy.yml + when: gogogo diff --git a/roles/jenkins-php-v1/templates/config.xml.j2 b/roles/jenkins-php-v1/templates/config.xml.j2 index 7b394b9..3ea6083 100644 --- a/roles/jenkins-php-v1/templates/config.xml.j2 +++ b/roles/jenkins-php-v1/templates/config.xml.j2 @@ -48,7 +48,9 @@ ${JENKINS_HOME}/workspace/${ITEM_FULL_NAME} ${ITEM_ROOTDIR}/builds - + + false + diff --git a/roles/jenkins-php-v1/templates/jenkins.model.JenkinsLocationConfiguration.xml.j2 b/roles/jenkins-php-v1/templates/jenkins.model.JenkinsLocationConfiguration.xml.j2 index baa1ba8..f1fe007 100644 --- a/roles/jenkins-php-v1/templates/jenkins.model.JenkinsLocationConfiguration.xml.j2 +++ b/roles/jenkins-php-v1/templates/jenkins.model.JenkinsLocationConfiguration.xml.j2 @@ -1,6 +1,5 @@ - - - http://{{ inventory_hostname }}:8080/ + {{ jenkins_admin_email }} + {{ nginx_vhost_ssl | ternary('https', 'http') }}://{{ nginx_vhost_main_hostname }}/ \ No newline at end of file diff --git a/roles/jenkins-php-v1/templates/jenkins.security.ResourceDomainConfiguration.xml.j2 b/roles/jenkins-php-v1/templates/jenkins.security.ResourceDomainConfiguration.xml.j2 new file mode 100644 index 0000000..f676165 --- /dev/null +++ b/roles/jenkins-php-v1/templates/jenkins.security.ResourceDomainConfiguration.xml.j2 @@ -0,0 +1,4 @@ + + + {{ nginx_vhost_ssl | ternary('https', 'http') }}://{{ nginx_vhost_resource_hostname }}/ + \ No newline at end of file diff --git a/roles/jenkins-php-v1/templates/nginx-vhost.j2 b/roles/jenkins-php-v1/templates/nginx-vhost.j2 new file mode 100644 index 0000000..00223e6 --- /dev/null +++ b/roles/jenkins-php-v1/templates/nginx-vhost.j2 @@ -0,0 +1,84 @@ + +{% if (nginx_vhost_ssl is defined and nginx_vhost_ssl) %} + +# The HTTP is a simple redirect to the HTTPS part +server { + listen 80; # Listen on port 80 for IPv4 requests + listen [::]:80; + server_name {{ nginx_vhost_main_hostname }} {{ nginx_vhost_resource_hostname }}; + rewrite ^ https://$http_host$request_uri? permanent; # force redirect http to https + server_tokens off; +} + +server { + listen 443; + listen [::]:443; + + ssl on; + ssl_certificate {{ nginx_vhost_ssl_certificate_file }}; + ssl_certificate_key {{ nginx_vhost_ssl_key_file }}; + ssl_session_timeout 5m; + ssl_session_cache shared:SSL:5m; + + #add_header Strict-Transport-Security "max-age=31536000; includeSubDomains"; + server_tokens off; + +{% else %} +# Plain HTTP +server { + listen 80; # Listen on port 80 for IPv4 requests + listen [::]:80; +{% endif %} + + server_name {{ nginx_vhost_main_hostname }} {{ nginx_vhost_resource_hostname }}; + + #this is the jenkins web root directory (mentioned in the /etc/default/jenkins file) + root /var/cache/jenkins/war/; + + access_log /var/log/nginx/jenkins-access.log; + error_log /var/log/nginx/jenkins-error.log; + ignore_invalid_headers off; #pass through headers from Jenkins which are considered invalid by Nginx server. + + location ~ "^/static/[0-9a-fA-F]{8}\/(.*)$" { + #rewrite all static files into requests to the root + #E.g /static/12345678/css/something.css will become /css/something.css + rewrite "^/static/[0-9a-fA-F]{8}\/(.*)" /$1 last; + } + + location /userContent { + #have nginx handle all the static requests to the userContent folder files + #note : This is the $JENKINS_HOME dir + root /var/lib/jenkins/; + if (!-f $request_filename){ + #this file does not exist, might be a directory or a /**view** url + rewrite (.*) /$1 last; + break; + } + sendfile on; + } + + location / { + sendfile off; + proxy_pass http://127.0.0.1:8080; + proxy_redirect default; + proxy_http_version 1.1; + + 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_max_temp_file_size 0; + + #this is the maximum upload size + client_max_body_size 10m; + client_body_buffer_size 128k; + + proxy_connect_timeout 90; + proxy_send_timeout 90; + proxy_read_timeout 90; + proxy_buffering off; + proxy_request_buffering off; # Required for HTTP CLI commands in Jenkins > 2.54 + proxy_set_header Connection ""; # Clear for keepalive + } + +}