Giter VIP home page Giter VIP logo

ansible-role-jenkins2's Introduction

Build Status

Ansible Role for Jenkins 2+

This Ansible role can be used to install and manage Jenkins 2.

Requirements

This role requires Ansible 2.4 or later, with either Ansible pipelining available or setfacl available on the system being managed (per Becoming an Unprivileged User).

The role currently supports Ubuntu 14.04 (Trusty) and Ubuntu 16.04 (Xenial), though contributtions for additional platform support are welcome!

Role Variables

This role supports the following variables, listed here with their default values from defaults/main.yml:

  • jenkins_release_line: 'weekly'
    • When set to long_term_support, the role will install the LTS releases of Jenkins.
    • When set to weekly, the role will install the weekly releases of Jenkins.
  • jenkins_release_update: true
    • If true, the Jenkins package (YUM, APT, etc.) will be upgraded to the latest version when this role is run.
  • jenkins_home: /var/lib/jenkins
    • The directory that (most of) Jenkins data will be stored.
    • Due to limitations of the Jenkins installer, the jenkins service account will still use the default as its home directory. This should really only come into play for SSH keys.
  • jenkins_port: 8080
    • The port that Jenkins will run on, for HTTP requests.
    • On most systems, this value will need to be over 1024, as Jenkins is not run as root.
  • jenkins_context_path: ''
    • The context path that Jenkins will be hosted at, e.g. /foo in http://localhost:8080/foo. Leave as '' to host at root path.
  • jenkins_url_external: ''
    • The external URL that users will use to access Jenkins. Gets set in the Jenkins config and used in emails, webhooks, etc.
    • If this is left empty/None, the configuration will not be set and Jenkins will try to auto-discover this (which won't work correctly if it's proxied).
  • jenkins_admin_username: (undefined)
    • If one of jenkins_admin_username and jenkins_admin_password are defined, both must be.
    • Override this variable to specify the Jenkins administrator credentials that should be used for each possible security realm.
    • If left undefined, the role will attempt to use anonymous authentication.
    • Note that the role will automatically detect if Jenkins is set to allow anonymous authentication (as is the case right after install) and handle it properly.
  • jenkins_admin_password: (undefined)
    • If one of jenkins_admin_username and jenkins_admin_password are defined, both must be.
    • Override this variable to specify the Jenkins administrator credentials that should be used for each possible security realm.
  • jenkins_session_timeout: 30
    • The number of minutes before Jenkins sessions timeout, i.e. how long logins are valid for.
    • Defaults to 30 minutes.
    • Can be set to 0 to never timeout.
  • jenkins_plugins_extra: []
    • Override this variable to install additional Jenkins plugins.
    • These would be in addition to the plugins recommended by Jenkins 2's new setup wizard, which are installed automatically by this role (see jenkins_plugins_recommended in defaults/main.yml).
  • jenkins_plugins_timeout: 60
  • jenkins_plugins_update: true
    • If true, the Jenkins plugins will be updated when this role is run. (Note that missing plugins will always be installed.)
  • jenkins_java_args_extra: ''
    • Additional options that will be added to JAVA_ARGS for the Jenkins process, such as the JVM memory settings, e.g. -Xmx4g.
  • jenkins_http_proxy_server, jenkins_http_proxy_port, jenkins_http_proxy_no_proxy_hosts: (all undefined)
    • These server the same function as the JVM's http.proxyHost, http.proxyPort, and http.nonProxyHosts system properties, except that the settings will be used for both HTTP and HTTPS requests.
    • Specifically, these settings will be used to configure:
      • The Jenkins JVM's http.proxyHost, http.proxyPort, https.proxyHost, https.proxyPort, and http.nonProxyHosts system properties, as documented on Java Networking and Proxies.
      • The Jenkins-specific proxy settings (which some plugins, such as the GitHub plugin, require), as documented on JenkinsBehindProxy.
      • The value of jenkins_http_proxy_no_proxy_hosts should be a list, e.g. ['localhost', 'example.com'].

Dependencies

This role does not have direct dependencies on other Ansible roles. However, it does require that a Java JRE be available on the system path.

Example Playbook

This role can be installed, as follows:

$ ansible-galaxy install karlmdavis.jenkins2

This role can be applied, as follows:

- hosts: some_box
  tasks:
    - import_role:
        name: karlmdavis.ansible-jenkins2
      vars:
        jenkins_plugins_extra:
          - github-oauth

Running Groovy Scripts to Configure Jenkins

After installing Jenkins, Groovy scripts can be run via Ansible to further customize Jenkins.

For example, here's how to install Jenkins and then configure Jenkins to use its HudsonPrivateSecurityRealm, for local Jenkins accounts:

- hosts: some_box
  tasks:

    - import_role:
        name: karlmdavis.ansible-jenkins2
      vars:
        # Won't be required on first run, but will be on prior runs (after
        # security has been enabled, per below).
        jenkins_admin_username: test
        jenkins_admin_password: supersecret

    # Ensure that Jenkins has restarted, if it needs to.
    - meta: flush_handlers

    # Configure security to use Jenkins-local accounts.
    - name: Configure Security
      jenkins_script:
        url: "{{ jenkins_url_local }}"
        user: "{{ jenkins_dynamic_admin_username | default(omit) }}"
        password: "{{ jenkins_dynamic_admin_password | default(omit) }}"
        script: |
          // These are the basic imports that Jenkin's interactive script console
          // automatically includes.
          import jenkins.*;
          import jenkins.model.*;
          import hudson.*;
          import hudson.model.*;

          // Configure the security realm, which handles authentication.
          def securityRealm = new hudson.security.HudsonPrivateSecurityRealm(false)
          if(!securityRealm.equals(Jenkins.instance.getSecurityRealm())) {
            Jenkins.instance.setSecurityRealm(securityRealm)

            // Create a user to login with. Ensure that user is bound to the
            // system-local `jenkins` user's SSH key, to ensure that this
            // account can be used with Jenkins' CLI.
            def testUser = securityRealm.createAccount("test", "supersecret")
            testUser.addProperty(new hudson.tasks.Mailer.UserProperty("[email protected]"));
            testUser.save()

            Jenkins.instance.save()
            println "Changed authentication."
          }

          // Configure the authorization strategy, which specifies who can do
          // what.
          def authorizationStrategy = new hudson.security.FullControlOnceLoggedInAuthorizationStrategy()
          if(!authorizationStrategy.equals(Jenkins.instance.getAuthorizationStrategy())) {
            authorizationStrategy.setAllowAnonymousRead(false)
            Jenkins.instance.setAuthorizationStrategy(authorizationStrategy)
            Jenkins.instance.save()
            println "Changed authorization."
          }
      register: shell_jenkins_security
      changed_when: "(shell_jenkins_security | success) and 'Changed' not in shell_jenkins_security.stdout"

Alternatively, the Groovy scripts can be stored as separate files and pulled in using a lookup(...), as below:

- hosts: some_box
  tasks:

    - import_role:
        name: karlmdavis.ansible-jenkins2
      vars:
        # Won't be required on first run, but will be on prior runs (after
        # security has been enabled, per below).
        jenkins_admin_username: test
        jenkins_admin_password: supersecret

    # Ensure that Jenkins has restarted, if it needs to.
    - meta: flush_handlers

    # Configure security to use Jenkins-local accounts.
    - name: Configure Security
      jenkins_script:
        url: "{{ jenkins_url_local }}"
        user: "{{ jenkins_dynamic_admin_username | default(omit) }}"
        password: "{{ jenkins_dynamic_admin_password | default(omit) }}"
        script: "{{ lookup('template', 'templates/jenkins_security.groovy.j2') }}"

License

This project is in the worldwide public domain. As stated in CONTRIBUTING:

This project is in the public domain within the United States, and copyright and related rights in the work worldwide are waived through the CC0 1.0 Universal public domain dedication.

All contributions to this project will be released under the CC0 dedication. By submitting a pull request, you are agreeing to comply with this waiver of copyright interest.

Author Information

This plugin was authored by Karl M. Davis (https://justdavis.com/karl/).

ansible-role-jenkins2's People

Contributors

haidaram avatar karlmdavis avatar kremers avatar prabjohns-atex avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

ansible-role-jenkins2's Issues

YUM packages not actually updated

Even though the role uses state: latest when installing the Jenkins YUM package, the package isn't updated.

After some research, it appears that what's happening is that the YUM cache isn't being updated first, so YUM doesn't know that there are newer packages to grab. Oops.

While I'm fixing this, it's probably worth adding an option to disable the auto-update, too, since I now provide that option for plugins.

Test failures with Ubuntu 14.04

The geerlingguy.java role does not work with Ubuntu 14.04 and oracle-java8 anymore. Maybe it is a good time to just ignore Ubuntu 14.04 and run tests with Ubuntu 18.04. Also, Ubuntu 14.04 has End of Standard Support (see: https://wiki.ubuntu.com/Releases).

fatal: [docker_container]: FAILED! => {"changed": false, "msg": "No package matching 'oracle-java8-installer' is available"}

Failure occurs in PR #62

Add config option for session timeout

Would be nice if it was easy to configure Jenkins' session timeout.

(Not strictly needed as a feature, since the Java args can be customized, but it's a convenient one to have called out.)

TASK [karlmdavis.jenkins2 : Add Jenkins APT Repository Failure

ansible 2.4.0.0
python version = 2.7.10 (default, Jul 15 2017, 17:16:57) [GCC 4.2.1 Compatible Apple LLVM 9.0.0 (clang-900.0.31)]
Vagrant 2.0.1
mac 10.13.1
ubuntu 16.04
openjdk version "1.8.0_151"
OpenJDK Runtime Environment (build 1.8.0_151-8u151-b12-0ubuntu0.16.04.2-b12)
OpenJDK 64-Bit Server VM (build 25.151-b12, mixed mode)

**provisioning with vagrant ansible causes the following failure:

TASK [karlmdavis.jenkins2 : include_tasks] *************************************
included: /Users/cbrownroberts/Dev/UML-Assets/scripts/libweb-initial-setup/LibWeb/provision/ansible/roles/karlmdavis.jenkins2/tasks/packages_Debian.yml for libweb

TASK [karlmdavis.jenkins2 : Update APT Cache] **********************************
ok: [libweb]

TASK [karlmdavis.jenkins2 : Install OS Dependencies] ***************************
ok: [libweb] => (item=[u'apt-transport-https'])

TASK [karlmdavis.jenkins2 : Determine APT Key and Repo to Use (Step 1)] ********
ok: [libweb]

TASK [karlmdavis.jenkins2 : Determine APT Key and Repo to Use (Step 2)] ********
ok: [libweb]

TASK [karlmdavis.jenkins2 : Add Jenkins APT Key] *******************************
changed: [libweb]

TASK [karlmdavis.jenkins2 : Remove Unused Jenkins APT Repositories] ************
ok: [libweb] => (item=deb http://pkg.jenkins-ci.org/debian binary/)
skipping: [libweb] => (item=deb https://pkg.jenkins.io/debian binary/)
ok: [libweb] => (item=deb https://pkg.jenkins.io/debian-stable binary/)

TASK [karlmdavis.jenkins2 : Add Jenkins APT Repository] ************************
fatal: [libweb]: FAILED! => {"changed": false, "failed": true, "module_stderr": "Shared connection to 127.0.0.1 closed.\r\n", "module_stdout": "Traceback (most recent call last):\r\n File "/tmp/ansible_LlFLZj/ansible_module_apt_repository.py", line 556, in \r\n main()\r\n File "/tmp/ansible_LlFLZj/ansible_module_apt_repository.py", line 544, in main\r\n cache.update()\r\n File "/usr/lib/python2.7/dist-packages/apt/cache.py", line 456, in update\r\n raise FetchFailedException()\r\napt.cache.FetchFailedException\r\n", "msg": "MODULE FAILURE", "rc": 0}
to retry, use: --limit @/Users/cbrownroberts/Dev/UML-Assets/scripts/libweb-initial-setup/LibWeb/provision/ansible/playbook.retry

PLAY RECAP *********************************************************************
libweb : ok=13 changed=2 unreachable=0 failed=1

Ansible failed to complete successfully. Any error output should be
visible above. Please fix these errors and try again.

Resolve Jenkins security warnings

After a clean install, this role leaves Jenkins configured in such a way that there are warnings about several not-recommended security settings:

  • CLI remoting is enabled
  • deprecated agent protocols are enabled
  • agent-master access control is disabled
  • CSRF is disabled

Switch to jenkins_script instead of Jenkins CLI

Recent Ansible releases provide a credible jenkins_script module that -- on the whole -- looks like a more robust solution than this role's current usage of the Jenkins CLI. It'd also lead to somewhat more readable code, which is nice.

Support operating in restricted Internet environments

If operating in an environment with a restrictive proxy server, we need the ability to specify exactly which of the YUM/APT mirrors will be used when installing Jenkins.

Also need to specify no_proxy on anything grabbing HTTP content from localhost.

Restart Service 'Jenkins' fails: 'TaskInclude' object has no attribute 'has_triggered'

The role fails with Ansible 2.1.0.0 because the handler Restart Service 'Jenkins' fails with the message ERROR! Unexpected Exception: 'TaskInclude' object has no attribute 'has_triggered'

Trace information:

.....
TASK [karlmdavis.jenkins2 : Configure JVM Arguments] ***************************
changed: [52.51.225.109]

RUNNING HANDLER [karlmdavis.jenkins2 : Restart Service 'jenkins'] **************
ERROR! Unexpected Exception: 'TaskInclude' object has no attribute 'has_triggered'
to see the full traceback, use -vvv

Ansible is installed as follows, and has the following version:

$ sudo apt-add-repository ppa:ansible/ansible -y
$ sudo apt-get update
$ sudo apt-get install ansible
$ ansible --version
ansible 2.1.0.0
  config file = /etc/ansible/ansible.cfg
  configured module search path = Default w/o overrides

After manual restart, when I run your playbook again, it gives me the following error:

TASK [karlmdavis.jenkins2 : Verify CLI] ****************************************
task path: /etc/ansible/roles/karlmdavis.jenkins2/tasks/cli_config.yml:94
fatal: [52.51.225.109]: FAILED! => {"failed": true, "msg": "Failed to set permissions on the temporary files Ansible needs to create when becoming an unprivileged user. For information on working around this, see https://docs.ansible.com/ansible/become.html#becoming-an-unprivileged-user"}

Which seems to be related to ansible 2.1 security changes: https://docs.ansible.com/ansible/become.html#becoming-an-unprivileged-user

When setting allow_world_readable_tmpfiles = True in /etc/ansible/ansible.cfg, the playbook continues until the handler is triggered again and fails with ERROR! Unexpected Exception: 'TaskInclude' object has no attribute 'has_triggered

Support for RHEL/CentOS 7

Hello - Thanks for creating and open sourcing this role. Is there any interest in supporting RHEL/CentOS 7? I can take a stab at working on it.

Example playbook fails in Vagrant

The Example Playbook in the README doesn't work out of the box.

Using for instance:

- hosts: all
  vars:
    jenkins_port: 8080

  roles:
     - karlmdavis.jenkins2

In Vagrant, gives:

TASK [karlmdavis.jenkins2 : Update APT Cache] **********************************
fatal: [jenkins]: FAILED! => {"changed": false, "failed": true, "msg": "Failed to lock apt for exclusive operation"}
        to retry, use: --limit @/Users/caleb/dev/ansible-galaxies/jenkins.retry

This is simple enough to fix by adding become: yes here or there.

Tons of deprecation warnings when running in Ansible 2.4

Ansible's task/role/variable inclusion facilities were rather drastically overhauled in v2.4. The changes are definitely all for the better, but lead to a bunch of deprecation warnings for any project that was previously using role or task includes, like this one.

Unfortunately, I don't see a backwards-compatible way for us to resolve those warnings in 2.4 while still supporting 2.0. We'll have to pick a point in time to drop support for 2.0... maybe six months from now? That'd be March or April of next year.

Ansible 2.5 isn't supported.

The roles jenkins_plugin implementation doesn't work correctly while using Ansible 2.5

failed: [10.0.0.201] (item=cloudbees-folder) => {"changed": false, "item": "cloudbees-folder", "msg": "The params option to jenkins_plugin was removed in Ansible 2.5 since it circumvents Ansible's option handling"}

Fixed the problem locally by modifying the Install Plugins and Update Plugins tasks. Removed the params implementation like so:

- name: Install Plugins
  jenkins_plugin:
    name: "{{ item }}"
    state: present
    jenkins_home: "{{ jenkins_home }}"
    url: "{{ jenkins_url_local }}"
    url_username: "{{ jenkins_dynamic_admin_username | default(omit) }}"
    url_password: "{{ jenkins_dynamic_admin_password | default(omit) }}"
    validate_certs: "{{ false if ansible_distribution_release == 'trusty' else true }}"
    timeout: "{{ jenkins_plugins_timeout }}"
  with_items:
    - "{{ jenkins_plugins_recommended }}"
    - "{{ jenkins_plugins_extra }}"
  become: true
  notify:
    - "Restart Service 'jenkins'"

Haven't made a merge request, since now I'm pretty sure this change will break Ansible 2.4 usage.

Thoughts, suggestions? Perhaps you @karlmdavis are willing to drop 2.4 support?

Add support for timeout installing plugins

jenkins_plugin supports a timeout, which is sometimes necessary if the plugin install is slow.

failed: [QAE-BND-001] (item=workflow-aggregator) => {"changed": false, "details": "Connection failure: timed out", "item": "workflow-aggregator", "msg": "Cannot install plugin."}
Changed plugins.yml to be:

- name: Install Plugins
  jenkins_plugin:
    name: "{{ item }}"
    state: present
    jenkins_home: "{{ jenkins_home }}"
    url: "{{ jenkins_url_local }}"
    params:
      url_username: "{{ jenkins_dynamic_admin_username | default(omit) }}"
    url_password: "{{ jenkins_dynamic_admin_password | default(omit) }}"
    validate_certs: "{{ false if ansible_distribution_release == 'trusty' else true }}"
    timeout: 120
  with_items:
    - "{{ jenkins_plugins_recommended }}"
    - "{{ jenkins_plugins_extra }}"
  become: true
  notify:
    - "Restart Service 'jenkins'"

- name: Update Plugins
  jenkins_plugin:
    name: "{{ item }}"
    state: latest
    jenkins_home: "{{ jenkins_home }}"
    url: "{{ jenkins_url_local }}"
    params:
      url_username: "{{ jenkins_dynamic_admin_username | default(omit) }}"
    url_password: "{{ jenkins_dynamic_admin_password | default(omit) }}"
    validate_certs: "{{ false if ansible_distribution_release == 'trusty' else true }}"
    timeout: 120
  with_items:
    - "{{ jenkins_plugins_recommended }}"
    - "{{ jenkins_plugins_extra }}"
  become: true
  notify:
    - "Restart Service 'jenkins'"

Rework HTTP proxy support

If Jenkins is running in a restricted/whitelisted-sites-only proxy server environment, and also points at a custom YUM repo, there may also be a need to not use the proxy server for those YUM connections.

This is kind of an obscure edge case, but one that I'm running into right now. So.

Verify CLI step fails without manual intervention

I found I had to manually disable security to get the cli to work, and a small amount of research couldn't turn up why the cli would work over http without securtiy being disabled - neither the -i or -auth options seem to be passed to the calls to jenkins-cli.

It gave an error of 'ERROR: anonymous is missing the Overall/Read permission'

So I manually switched security off, ran the role again, and it worked.

PS Thanks for the role!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.