├── .ansible-lint ├── .github └── workflows │ └── molecule.yml ├── .gitignore ├── .yamllint ├── LICENSE ├── README.md ├── defaults └── main.yml ├── handlers └── main.yml ├── meta └── main.yml ├── molecule ├── default │ ├── Dockerfile.j2 │ ├── converge.yml │ ├── molecule.yml │ ├── prepare.yml │ └── side_effect.yml └── vagrant │ ├── molecule.yml │ └── requirements.txt ├── tasks ├── main.yml ├── setup_debian.yml ├── setup_plugin.yml ├── setup_plugin_binaries.yml ├── setup_plugin_marketplace.yml ├── setup_prepare.yml └── setup_sonarqube.yml ├── templates ├── sonar.properties.j2 └── sonar.service.j2 └── vars └── main.yml /.ansible-lint: -------------------------------------------------------------------------------- 1 | --- 2 | skip_list: 3 | - '204' 4 | -------------------------------------------------------------------------------- /.github/workflows/molecule.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Molecule 3 | on: 4 | push: 5 | pull_request: 6 | branches: 7 | - master 8 | jobs: 9 | molecule: 10 | runs-on: ubuntu-latest 11 | strategy: 12 | fail-fast: false 13 | max-parallel: 4 14 | matrix: 15 | distro: 16 | - centos7 17 | - debian9 18 | steps: 19 | - uses: actions/checkout@v2 20 | - name: python 21 | uses: actions/setup-python@v2 22 | with: 23 | python-version: '3.8' 24 | - name: dependencies 25 | run: pip3 install yamllint ansible ansible-lint flake8 molecule[docker] docker 26 | - name: molecule 27 | run: molecule test 28 | env: 29 | PY_COLORS: '1' 30 | ANSIBLE_FORCE_COLOR: '1' 31 | MOLECULE_DISTRO: ${{ matrix.distro }} 32 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | *.retry 3 | .vagrant 4 | tests/roles 5 | tests/galaxy_roles 6 | __pycache__ 7 | INSTALL.rst 8 | -------------------------------------------------------------------------------- /.yamllint: -------------------------------------------------------------------------------- 1 | --- 2 | # Based on ansible-lint config 3 | extends: default 4 | 5 | rules: 6 | braces: 7 | max-spaces-inside: 1 8 | level: error 9 | brackets: 10 | max-spaces-inside: 1 11 | level: error 12 | colons: 13 | max-spaces-after: -1 14 | level: error 15 | commas: 16 | max-spaces-after: -1 17 | level: error 18 | comments: disable 19 | comments-indentation: disable 20 | document-start: disable 21 | empty-lines: 22 | max: 3 23 | level: error 24 | hyphens: 25 | level: error 26 | indentation: disable 27 | key-duplicates: enable 28 | line-length: disable 29 | new-line-at-end-of-file: disable 30 | new-lines: 31 | type: unix 32 | trailing-spaces: disable 33 | truthy: disable 34 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Ansible Role: SonarQube ([lrk.sonarqube](https://galaxy.ansible.com/lrk/sonarqube/)) 2 | ========= 3 | [![Molecule](https://github.com/lrk/ansible-role-sonarqube/actions/workflows/molecule.yml/badge.svg)](https://github.com/lrk/ansible-role-sonarqube/actions/workflows/molecule.yml) 4 | [![Galaxy](https://img.shields.io/badge/galaxy-lrk.sonarqube-blue.svg)](https://galaxy.ansible.com/lrk/sonarqube) 5 | ![Ansible](https://img.shields.io/ansible/role/d/20831.svg) 6 | ![Ansible](https://img.shields.io/badge/dynamic/json.svg?label=min_ansible_version&url=https%3A%2F%2Fgalaxy.ansible.com%2Fapi%2Fv1%2Froles%2F20831%2F&query=$.min_ansible_version) 7 | ![Ansible](https://img.shields.io/ansible/quality/20831) 8 | 9 | An Ansible Role that install [SonarQube](https://www.sonarqube.org). 10 | 11 | Supported OSes 12 | -------------- 13 | This role as been tested on the following OSes: 14 | 15 | - EL - 7 16 | - Debian - Stretch 17 | 18 | Requirements 19 | ------------ 20 | 21 | [SonarQube requirements](https://docs.sonarqube.org/display/SONAR/Requirements) are: 22 | - Oracle JRE 11 onwards or OpenJDK 11 onwards installed on your machine. 23 | 24 | For production environment, make sure to set the `sonar_db_embedded` variable to false and to configure sonar_db_* variables. 25 | 26 | SonarQube support following databases: MySQL, Oracle, PostgreSQL and Microsoft SQLServer. 27 | 28 | For further informations, please dive into [SonarQube requirements](https://docs.sonarqube.org/display/SONAR/Requirements) 29 | 30 | 31 | SonarQube plugin installation 32 | ----------------------------- 33 | 34 | This role supports plugin installation based on "[SonarQube Install a Plugin](https://docs.sonarqube.org/latest/setup/install-plugin/)" procedure. Both marketplace and manual methods are supported. 35 | 36 | Please note that this role does not handle previously installed plugins. 37 | You **have to** remove previous versions yourself. 38 | 39 | To install plugins list them in `sonar_plugins` dictionary, the following options are available: 40 | - `name`: plugin name, for marketplace plugin it should be the name of plugin's manifest (json) from [here](https://update.sonarsource.org), for manual plugins it can be name of the plugin folder from [here](https://binaries.sonarsource.com/Distribution) or provide `url` option (see below); 41 | - `version`: plugin version; 42 | - `commercial`: is this commercial plugin (an another download location actually), make sense only for manual plugins; 43 | - `url`: link to plugin's jar, if provided, role doesn't try to find plugin and use this link, doesn't make sense for marketplace plugins because download url should be provided in manifest; 44 | - `marketplace`: is this manual or marketplace plugin, default is false. 45 | 46 | Example: 47 | ```yml 48 | sonar_plugins: 49 | - name: "sonar-city-model-plugin" 50 | version: "3.3" 51 | commercial: true 52 | url: "http://www.qalitax.com/descargas/product/sonar-city-model-plugin-3.3.jar?customerSurnames=update-center&customerCompany=sonar-update-center&customerName=sonarqube&customerEmail=downloads@excentia.es"} 53 | - name: "ansible" 54 | version: "2.4.0" 55 | marketplace: true 56 | ``` 57 | 58 | How to test locally with vagrant 59 | -------------------------------- 60 | 61 | 1. Install [Vagrant](https://www.vagrantup.com) and [VirtualBox](https://www.virtualbox.org/wiki/Downloads). 62 | 2. Initialize virtualenv and setup requirements, for example: 63 | ``` 64 | python -m venv ~/.virtualenvs/molecule 65 | . ~/.virtualenvs/molecule/bin/activate 66 | pip install -r molecule/vagrant/requirements.txt 67 | ``` 68 | 3. Run tests (CentOS box is used by default): 69 | ``` 70 | molecule test -s vagrant 71 | ``` 72 | 4. (optional) Run tests for an another OS (ubuntu in this case): 73 | ``` 74 | MOLECULE_DISTRO=ubuntu/trusty64 molecule test -s vagrant 75 | ``` 76 | 77 | Role Variables 78 | -------------- 79 | 80 | Available variables along with default values are listed below (see `defaults/main.yml`) 81 | 82 | ```yml 83 | --- 84 | --- 85 | # defaults file for ansible-role-sonarqube/ 86 | 87 | # SonarQube Install directory 88 | sonar_install_directory: /opt/sonarqube 89 | 90 | # SonarQube base directory 91 | sonar_base_dir: "{{ sonar_install_directory }}/sonarqube-{{ sonar_version }}" 92 | 93 | # SonarQube daemon directory 94 | sonar_daemon_dir: "{{ sonar_base_dir }}/bin/linux-x86-{{ ansible_userspace_bits }}" 95 | 96 | # SonarQube conf directory 97 | sonar_conf_dir: "{{ sonar_base_dir }}/conf" 98 | 99 | sonar_logs_dir: "/var/log/sonarqube" 100 | 101 | # Paths to persistent data files (embedded database and search index) 102 | sonar_data_dir: "{{ sonar_base_dir }}/data" 103 | 104 | # Paths to temporary files 105 | sonar_temp_dir: "{{ sonar_base_dir }}/temp" 106 | 107 | # SonarQube version to install 108 | sonar_version: 5.6.7 109 | 110 | # SonarQube system group 111 | sonar_group: sonar 112 | 113 | # SonarQube system user 114 | sonar_user: sonar 115 | 116 | # SonarQube service LimitNOFILE parameter 117 | sonar_limitnofile: 65536 118 | 119 | # SonarQube plugins to install (see detailed description above) 120 | sonar_plugins: [] 121 | 122 | # Use the embedded H2 database, not for production environmnet 123 | sonar_db_embedded: true 124 | sonar_db_embedded_port: 9092 125 | 126 | # SonarQube JDBC Credentials 127 | sonar_db_user: "" 128 | sonar_db_pass: "" 129 | 130 | # SonarQube JDBC URL 131 | # examples (from default sonar.properties file): 132 | #----- MySQL 5.6 or greater 133 | # Only InnoDB storage engine is supported (not myISAM). 134 | # Only the bundled driver is supported. It can not be changed. 135 | #sonar_jdbc_url=jdbc:mysql://localhost:3306/sonar?useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true&useConfigs=maxPerformance 136 | #----- Oracle 11g/12c 137 | # - Only thin client is supported 138 | # - Only versions 11.2.x and 12.x of Oracle JDBC driver are supported 139 | # - The JDBC driver must be copied into the directory extensions/jdbc-driver/oracle/ 140 | # - If you need to set the schema, please refer to http://jira.sonarsource.com/browse/SONAR-5000 141 | #sonar_jdbc_url=jdbc:oracle:thin:@localhost:1521/XE 142 | #----- PostgreSQL 8.x/9.x 143 | # If you don't use the schema named "public", please refer to http://jira.sonarsource.com/browse/SONAR-5000 144 | #sonar_jdbc_url=jdbc:postgresql://localhost/sonar 145 | 146 | #----- Microsoft SQLServer 2008/2012/2014 and SQL Azure 147 | # A database named sonar must exist and its collation must be case-sensitive (CS) and accent-sensitive (AS) 148 | # Use the following connection string if you want to use integrated security with Microsoft Sql Server 149 | # Do not set sonar.jdbc.username or sonar.jdbc.password property if you are using Integrated Security 150 | # For Integrated Security to work, you have to download the Microsoft SQL JDBC driver package from 151 | # http://www.microsoft.com/en-us/download/details.aspx?displaylang=en&id=11774 152 | # and copy sqljdbc_auth.dll to your path. You have to copy the 32 bit or 64 bit version of the dll 153 | # depending upon the architecture of your server machine. 154 | # This version of SonarQube has been tested with Microsoft SQL JDBC version 4.1 155 | #sonar_jdbc_url=jdbc:sqlserver://localhost;databaseName=sonar;integratedSecurity=true 156 | # Use the following connection string if you want to use SQL Auth while connecting to MS Sql Server. 157 | # Set the sonar.jdbc.username and sonar.jdbc.password appropriately. 158 | #sonar_jdbc_url=jdbc:sqlserver://localhost;databaseName=sonar 159 | 160 | sonar_jdbc_url: "" 161 | 162 | # SonarQube JDBC maximum number of active connection 163 | sonar_jdbc_maxactive: 60 164 | 165 | # The maximum number of connections that can remain idle in the 166 | # pool, without extra ones being released, or negative for no limit. 167 | sonar_jdbc_maxidle: 5 168 | 169 | # The minimum number of connections that can remain idle in the pool, 170 | # without extra ones being created, or zero to create none. 171 | sonar_jdbc_minidle: 2 172 | 173 | 174 | # The maximum number of milliseconds that the pool will wait (when there 175 | # are no available connections) for a connection to be returned before 176 | # throwing an exception, or <= 0 to wait indefinitely. 177 | sonar_jdbc_maxwait: 5000 178 | 179 | sonar_jdbc_min_evictable_idle_time_millis: 600000 180 | sonar_jdbc_time_between_eviction_runs_millis: 30000 181 | 182 | 183 | # SonarQube Web Server configuration 184 | # sonar_web_java_opts: "-Xmx512m -Xms128m -XX:+HeapDumpOnOutOfMemoryError -Djava.net.preferIPv4Stack=true" 185 | sonar_web_java_opts: "" 186 | 187 | # Same as previous property, but allows to not repeat all other settings like -Xmx 188 | sonar_web_java_additional_opts: "" 189 | 190 | # Binding IP address. For servers with more than one IP address, this property specifies which 191 | # address will be used for listening on the specified ports. 192 | # By default, ports will be used on all IP addresses associated with the server. 193 | sonar_web_host: 0.0.0.0 194 | 195 | # Web context. When set, it must start with forward slash (for example /sonarqube). 196 | # The default value is root context (empty value). 197 | sonar_web_context: "" 198 | 199 | # TCP port for incoming HTTP connections. Default value is 9000. 200 | sonar_web_port: 9000 201 | 202 | # The maximum number of connections that the server will accept and process at any given time. 203 | # When this number has been reached, the server will not accept any more connections until 204 | # the number of connections falls below this value. The operating system may still accept connections 205 | # based on the sonar.web.connections.acceptCount property. The default value is 50. 206 | sonar_web_http_max_threads: 50 207 | 208 | # The minimum number of threads always kept running. The default value is 5. 209 | sonar_web_http_min_threads: 5 210 | 211 | # The maximum queue length for incoming connection requests when all possible request processing 212 | # threads are in use. Any requests received when the queue is full will be refused. 213 | # The default value is 25. 214 | sonar_web_http_accept_count: 25 215 | 216 | # TCP port for incoming AJP connections. Disabled if value is -1. Disabled by default. 217 | sonar_ajp_port: -1 218 | 219 | #-------------------------------------------------------------------------------------------------- 220 | # COMPUTE ENGINE 221 | # The Compute Engine is responsible for processing background tasks. 222 | # Compute Engine is executed in a dedicated Java process. Default heap size is 512Mb. 223 | # Use the following property to customize JVM options. 224 | # Recommendations: 225 | # 226 | # The HotSpot Server VM is recommended. The property -server should be added if server mode 227 | # is not enabled by default on your environment: 228 | # http://docs.oracle.com/javase/8/docs/technotes/guides/vm/server-class.html 229 | # 230 | # sonar_ce_java_opts: "-Xmx512m -Xms128m -XX:+HeapDumpOnOutOfMemoryError -Djava.net.preferIPv4Stack=true" 231 | sonar_ce_java_opts: "" 232 | 233 | # Same as previous property, but allows to not repeat all other settings like -Xmx 234 | sonar_ce_java_additional_opts: "" 235 | 236 | # The number of workers in the Compute Engine. Value must be greater than zero. 237 | # By default the Compute Engine uses a single worker and therefore processes tasks one at a time. 238 | # Recommendations: 239 | # 240 | # Using N workers will require N times as much Heap memory (see property 241 | # sonar.ce.javaOpts to tune heap) and produce N times as much IOs on disk, database and 242 | # Elasticsearch. The number of workers must suit your environment. 243 | sonar_ce_worker_count: 1 244 | 245 | #-------------------------------------------------------------------------------------------------- 246 | # ELASTICSEARCH 247 | # Elasticsearch is used to facilitate fast and accurate information retrieval. 248 | # It is executed in a dedicated Java process. Default heap size is 1Gb. 249 | 250 | # JVM options of Elasticsearch process 251 | # Recommendations: 252 | # 253 | # Use HotSpot Server VM. The property -server should be added if server mode 254 | # is not enabled by default on your environment: 255 | # http://docs.oracle.com/javase/8/docs/technotes/guides/vm/server-class.html 256 | # 257 | sonar_search_java_opts: "-Xmx1G -Xms256m -Xss1m -Djava.net.preferIPv4Stack=true -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=75 -XX:+UseCMSInitiatingOccupancyOnly -XX:+HeapDumpOnOutOfMemoryError" 258 | 259 | # Same as previous property, but allows to not repeat all other settings like -Xmx 260 | sonar_search_java_additional_opts: "" 261 | 262 | # Elasticsearch port. Default is 9001. Use 0 to get a free port. 263 | # As a security precaution, should be blocked by a firewall and not exposed to the Internet. 264 | sonar_search_port: 9001 265 | 266 | # Elasticsearch host. The search server will bind this address and the search client will connect to it. 267 | # Default is 127.0.0.1. 268 | # As a security precaution, should NOT be set to a publicly available address. 269 | sonar_search_host: 127.0.0.1 270 | 271 | 272 | #-------------------------------------------------------------------------------------------------- 273 | # UPDATE CENTER 274 | 275 | # Update Center requires an internet connection to request https://update.sonarsource.org 276 | # It is enabled by default. 277 | sonar_updatecenter_activate: true 278 | 279 | # HTTP proxy (default none) 280 | http_proxy_host: "" 281 | http_proxy_port: "" 282 | # HTTPS proxy (defaults are values of http.proxyHost and http.proxyPort) 283 | https_proxy_host: "" 284 | https_proxy_port: "" 285 | 286 | # NT domain name if NTLM proxy is used 287 | http_auth_ntlm_domain: "" 288 | 289 | # SOCKS proxy (default none) 290 | socks_proxy_host: "" 291 | socks_proxy_port: "" 292 | 293 | # Proxy authentication (used for HTTP, HTTPS and SOCKS proxies) 294 | http_proxy_user: "" 295 | http_proxy_password: "" 296 | 297 | #-------------------------------------------------------------------------------------------------- 298 | # LOGGING 299 | 300 | # Level of logs. Supported values are INFO(default), DEBUG and TRACE (DEBUG + SQL + ES requests) 301 | sonar_log_level: "INFO" 302 | 303 | # Rolling policy of log files 304 | # - based on time if value starts with "time:", for example by day ("time:yyyy-MM-dd") 305 | # or by month ("time:yyyy-MM") 306 | # - based on size if value starts with "size:", for example "size:10MB" 307 | # - disabled if value is "none". That needs logs to be managed by an external system like logrotate. 308 | sonar_log_rolling_policy: "time:yyyy-MM-dd" 309 | 310 | # Maximum number of files to keep if a rolling policy is enabled. 311 | # - maximum value is 20 on size rolling policy 312 | # - unlimited on time rolling policy. Set to zero to disable old file purging. 313 | sonar_log_max_files: 7 314 | 315 | # Access log is the list of all the HTTP requests received by server. If enabled, it is stored 316 | # in the file {sonar.path.logs}/access.log. This file follows the same rolling policy as for 317 | # sonar.log (see sonar.log.rollingPolicy and sonar.log.maxFiles). 318 | sonar_web_access_logs_enable: true 319 | 320 | # Format of access log. It is ignored if sonar.web.accessLogs.enable=false. Possible values are: 321 | # - "common" is the Common Log Format, shortcut to: %h %l %u %user %date "%r" %s %b 322 | # - "combined" is another format widely recognized, shortcut to: %h %l %u [%t] "%r" %s %b "%i{Referer}" "%i{User-Agent}" 323 | # - else a custom pattern. See http://logback.qos.ch/manual/layouts.html#AccessPatternLayout. 324 | # If SonarQube is behind a reverse proxy, then the following value allows to display the correct remote IP address: 325 | sonar_web_access_logs_pattern: "%i{X-Forwarded-For} %l %u [%t] \"%r\" %s %b \"%i{Referer}\" \"%i{User-Agent}\"" 326 | 327 | #-------------------------------------------------------------------------------------------------- 328 | # LDAP 329 | # Ldap configuration for ldap auth plugin 330 | # see https://docs.sonarqube.org/latest/instance-administration/delegated-auth/ for more details and description of properties 331 | # 332 | # Example: 333 | # sonar_ldap: 334 | # authenticator_downcase: false 335 | # url: 'ldap://your_ldap_url' 336 | # bind_dn: 'cn=sonaruser,o=example,o=com' 337 | # bind_password: 'MyBindPassword' 338 | # user_base_dn: 'o=users,o=example,o=com' 339 | # authentication: simple 340 | # realm: 'example.org' 341 | # context_factory_class: com.sun.jndi.ldap.LdapCtxFactory 342 | # start_tls: false 343 | # follow_referrals: true 344 | # user_base_dn: 'cn=users,dc=example,dc=org' 345 | # user_request: '(&(objectClass=inetOrgPerson)(uid={login}))' 346 | # user_real_name_attribute: 'cn' 347 | # user_email_attribute: 'mail' 348 | # group_base_dn: 'o=groups,o=example,o=com' 349 | # group_request: '(&(objectClass=groupOfNames)(member={dn}))' 350 | # group_id_attribute: 'sAMAccountName' 351 | # 352 | # default: undefined 353 | # sonar_ldap: 354 | 355 | #-------------------------------------------------------------------------------------------------- 356 | # OTHERS 357 | 358 | # Delay in seconds between processing of notification queue. Default is 60 seconds. 359 | sonar_notifications_delay: 60 360 | 361 | # Pass any custom Java properties to sonar.properties 362 | sonar_additional_properties: {} 363 | 364 | #-------------------------------------------------------------------------------------------------- 365 | # OVERRIDE DEFAULT INTERNAL VALUES 366 | 367 | # If present, overwrite the default sonarqube download url. 368 | sonar_download_url: "https://your_url" 369 | 370 | # If present, overwrite the default sonarqube plugin base url. 371 | sonar_plugin_baseurl: "https://your_url" 372 | 373 | # If present, overwrite the default sonarqube commercial plugin base url. 374 | sonar_commercial_plugin_baseurl: "https://your_url" 375 | #-------------------------------------------------------------------------------------------------- 376 | # DEVELOPMENT - only for developers 377 | # The following properties MUST NOT be used in production environments. 378 | 379 | # Dev mode allows to reload web sources on changes and to restart server when new versions 380 | # of plugins are deployed. 381 | sonar_web_dev: false 382 | 383 | # Path to webapp sources for hot-reloading of Ruby on Rails, JS and CSS (only core, 384 | # plugins not supported). 385 | sonar_web_dev_sources: "" 386 | 387 | # Elasticsearch HTTP connector, for example for KOPF: 388 | # http://lmenezes.com/elasticsearch-kopf/?location=http://localhost:9010 389 | sonar_search_http_port: -1 390 | ``` 391 | 392 | Dependencies 393 | ------------ 394 | 395 | There are no direct dependencies. JDK should be installed first. 396 | 397 | Example Playbook 398 | ---------------- 399 | 400 | ``` 401 | - hosts: servers 402 | pre_tasks: 403 | - name: Install package dependencies. 404 | package: 405 | name: "{{ item }}" 406 | state: "present" 407 | with_items: 408 | - unzip 409 | roles: 410 | - lrk.sonarqube 411 | ``` 412 | 413 | Upgrade 414 | ------------ 415 | Please test upgrade in staging environment first 416 | 417 | Process consist of the next steps: 418 | 419 | 1. Change the var `sonar_version` 420 | 2. Review the var `sonar_plugins` in accordance with https://docs.sonarqube.org/latest/instance-administration/plugin-version-matrix/ 421 | 3. Run the role over existing installation. Ansible will: 422 | - create the installation folder 423 | - place here the binaries of new SonarQube with plugins 424 | - stop the currently running service 425 | - update configs 426 | - start service again 427 | - ensure web-service started and SonarQube version number appear in web.log 428 | - ensure that running Sonar version correspond to expected 429 | 4. Then you need open http://yourSonarQubeServerURL/setup and follow the setup instructions as described in https://docs.sonarqube.org/latest/setup/upgrading/ (role output leave a reminder for this) 430 | 431 | Please pay your attention: 432 | - role doesn't backup the database 433 | - role doesn't compare the versions. Please avoid of making downgrade by mistake 434 | - role doesn't remove the folder with previous installation, so after upgrade the path specified in variable `sonar_install_directory` will contain more than one `sonar_base_dir` 435 | 436 | License 437 | ------- 438 | 439 | Apache License Version 2.0 440 | 441 | References 442 | ---------- 443 | - [SonarQube Documentation](https://docs.sonarqube.org/display/SONAR/Documentation) 444 | 445 | Author Information 446 | ------------------ 447 | 448 | This role was created by [Lrk](https://github.com/lrk). 449 | -------------------------------------------------------------------------------- /defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # defaults file for ansible-role-sonarqube/ 3 | 4 | # SonarQube Install directory 5 | sonar_install_directory: /opt/sonarqube 6 | 7 | # SonarQube base directory 8 | sonar_base_dir: "{{ sonar_install_directory }}/sonarqube-{{ sonar_version }}" 9 | 10 | # SonarQube daemon directory 11 | sonar_daemon_dir: "{{ sonar_base_dir }}/bin/linux-x86-{{ ansible_userspace_bits }}" 12 | 13 | # SonarQube conf directory 14 | sonar_conf_dir: "{{ sonar_base_dir }}/conf" 15 | 16 | sonar_logs_dir: "/var/log/sonarqube" 17 | 18 | # Paths to persistent data files (embedded database and search index) 19 | sonar_data_dir: "{{ sonar_base_dir }}/data" 20 | 21 | # Paths to temporary files 22 | sonar_temp_dir: "{{ sonar_base_dir }}/temp" 23 | 24 | # SonarQube version to install 25 | sonar_version: 7.3 26 | 27 | # SonarQube system group 28 | sonar_group: sonar 29 | 30 | # SonarQube system user 31 | sonar_user: sonar 32 | 33 | # SonarQube service LimitNOFILE parameter 34 | sonar_limitnofile: 65536 35 | 36 | # SonarQube plugins to install 37 | sonar_plugins: [] 38 | # - { name: "plugin name", version: "1.0", commercial: false, url: 'optional'} 39 | 40 | # Use the embedded H2 database, not for production environmnet 41 | sonar_db_embedded: true 42 | sonar_db_embedded_port: 9092 43 | 44 | # SonarQube JDBC Credentials 45 | sonar_db_user: "" 46 | sonar_db_pass: "" 47 | 48 | # SonarQube JDBC URL 49 | # examples (from default sonar.properties file): 50 | #----- MySQL 5.6 or greater 51 | # Only InnoDB storage engine is supported (not myISAM). 52 | # Only the bundled driver is supported. It can not be changed. 53 | #sonar_jdbc_url=jdbc:mysql://localhost:3306/sonar?useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true&useConfigs=maxPerformance 54 | #----- Oracle 11g/12c 55 | # - Only thin client is supported 56 | # - Only versions 11.2.x and 12.x of Oracle JDBC driver are supported 57 | # - The JDBC driver must be copied into the directory extensions/jdbc-driver/oracle/ 58 | # - If you need to set the schema, please refer to http://jira.sonarsource.com/browse/SONAR-5000 59 | #sonar_jdbc_url=jdbc:oracle:thin:@localhost:1521/XE 60 | #----- PostgreSQL 8.x/9.x 61 | # If you don't use the schema named "public", please refer to http://jira.sonarsource.com/browse/SONAR-5000 62 | #sonar_jdbc_url=jdbc:postgresql://localhost/sonar 63 | 64 | #----- Microsoft SQLServer 2008/2012/2014 and SQL Azure 65 | # A database named sonar must exist and its collation must be case-sensitive (CS) and accent-sensitive (AS) 66 | # Use the following connection string if you want to use integrated security with Microsoft Sql Server 67 | # Do not set sonar.jdbc.username or sonar.jdbc.password property if you are using Integrated Security 68 | # For Integrated Security to work, you have to download the Microsoft SQL JDBC driver package from 69 | # http://www.microsoft.com/en-us/download/details.aspx?displaylang=en&id=11774 70 | # and copy sqljdbc_auth.dll to your path. You have to copy the 32 bit or 64 bit version of the dll 71 | # depending upon the architecture of your server machine. 72 | # This version of SonarQube has been tested with Microsoft SQL JDBC version 4.1 73 | #sonar_jdbc_url=jdbc:sqlserver://localhost;databaseName=sonar;integratedSecurity=true 74 | # Use the following connection string if you want to use SQL Auth while connecting to MS Sql Server. 75 | # Set the sonar.jdbc.username and sonar.jdbc.password appropriately. 76 | #sonar_jdbc_url=jdbc:sqlserver://localhost;databaseName=sonar 77 | 78 | sonar_jdbc_url: "" 79 | 80 | # SonarQube JDBC maximum number of active connection 81 | sonar_jdbc_maxactive: 60 82 | 83 | # The maximum number of connections that can remain idle in the 84 | # pool, without extra ones being released, or negative for no limit. 85 | sonar_jdbc_maxidle: 5 86 | 87 | # The minimum number of connections that can remain idle in the pool, 88 | # without extra ones being created, or zero to create none. 89 | sonar_jdbc_minidle: 2 90 | 91 | 92 | # The maximum number of milliseconds that the pool will wait (when there 93 | # are no available connections) for a connection to be returned before 94 | # throwing an exception, or <= 0 to wait indefinitely. 95 | sonar_jdbc_maxwait: 5000 96 | 97 | sonar_jdbc_min_evictable_idle_time_millis: 600000 98 | sonar_jdbc_time_between_eviction_runs_millis: 30000 99 | 100 | 101 | # SonarQube Web Server configuration 102 | # sonar_web_java_opts: "-Xmx512m -Xms128m -XX:+HeapDumpOnOutOfMemoryError -Djava.net.preferIPv4Stack=true" 103 | sonar_web_java_opts: "" 104 | 105 | # Same as previous property, but allows to not repeat all other settings like -Xmx 106 | sonar_web_java_additional_opts: "" 107 | 108 | # Binding IP address. For servers with more than one IP address, this property specifies which 109 | # address will be used for listening on the specified ports. 110 | # By default, ports will be used on all IP addresses associated with the server. 111 | sonar_web_host: 0.0.0.0 112 | 113 | # Web context. When set, it must start with forward slash (for example /sonarqube). 114 | # The default value is root context (empty value). 115 | sonar_web_context: "" 116 | 117 | # TCP port for incoming HTTP connections. Default value is 9000. 118 | sonar_web_port: 9000 119 | 120 | # The maximum number of connections that the server will accept and process at any given time. 121 | # When this number has been reached, the server will not accept any more connections until 122 | # the number of connections falls below this value. The operating system may still accept connections 123 | # based on the sonar.web.connections.acceptCount property. The default value is 50. 124 | sonar_web_http_max_threads: 50 125 | 126 | # The minimum number of threads always kept running. The default value is 5. 127 | sonar_web_http_min_threads: 5 128 | 129 | # The maximum queue length for incoming connection requests when all possible request processing 130 | # threads are in use. Any requests received when the queue is full will be refused. 131 | # The default value is 25. 132 | sonar_web_http_accept_count: 25 133 | 134 | # TCP port for incoming AJP connections. Disabled if value is -1. Disabled by default. 135 | sonar_ajp_port: -1 136 | 137 | #-------------------------------------------------------------------------------------------------- 138 | # COMPUTE ENGINE 139 | # The Compute Engine is responsible for processing background tasks. 140 | # Compute Engine is executed in a dedicated Java process. Default heap size is 512Mb. 141 | # Use the following property to customize JVM options. 142 | # Recommendations: 143 | # 144 | # The HotSpot Server VM is recommended. The property -server should be added if server mode 145 | # is not enabled by default on your environment: 146 | # http://docs.oracle.com/javase/8/docs/technotes/guides/vm/server-class.html 147 | # 148 | # sonar_ce_java_opts: "-Xmx512m -Xms128m -XX:+HeapDumpOnOutOfMemoryError -Djava.net.preferIPv4Stack=true" 149 | sonar_ce_java_opts: "" 150 | 151 | # Same as previous property, but allows to not repeat all other settings like -Xmx 152 | sonar_ce_java_additional_opts: "" 153 | 154 | # The number of workers in the Compute Engine. Value must be greater than zero. 155 | # By default the Compute Engine uses a single worker and therefore processes tasks one at a time. 156 | # Recommendations: 157 | # 158 | # Using N workers will require N times as much Heap memory (see property 159 | # sonar.ce.javaOpts to tune heap) and produce N times as much IOs on disk, database and 160 | # Elasticsearch. The number of workers must suit your environment. 161 | sonar_ce_worker_count: 1 162 | 163 | #-------------------------------------------------------------------------------------------------- 164 | # ELASTICSEARCH 165 | # Elasticsearch is used to facilitate fast and accurate information retrieval. 166 | # It is executed in a dedicated Java process. Default heap size is 1Gb. 167 | 168 | # JVM options of Elasticsearch process 169 | # Recommendations: 170 | # 171 | # Use HotSpot Server VM. The property -server should be added if server mode 172 | # is not enabled by default on your environment: 173 | # http://docs.oracle.com/javase/8/docs/technotes/guides/vm/server-class.html 174 | # 175 | # sonar_search_java_opts: "-Xmx1G -Xms1G -Xss256k -Djava.net.preferIPv4Stack=true -XX:CMSInitiatingOccupancyFraction=75 -XX:+UseCMSInitiatingOccupancyOnly -XX:+HeapDumpOnOutOfMemoryError" 176 | sonar_search_java_opts: "" 177 | 178 | # Same as previous property, but allows to not repeat all other settings like -Xmx 179 | sonar_search_java_additional_opts: "" 180 | 181 | # Elasticsearch port. Default is 9001. Use 0 to get a free port. 182 | # As a security precaution, should be blocked by a firewall and not exposed to the Internet. 183 | sonar_search_port: 9001 184 | 185 | # Elasticsearch host. The search server will bind this address and the search client will connect to it. 186 | # Default is 127.0.0.1. 187 | # As a security precaution, should NOT be set to a publicly available address. 188 | sonar_search_host: 127.0.0.1 189 | 190 | 191 | #-------------------------------------------------------------------------------------------------- 192 | # UPDATE CENTER 193 | 194 | # Update Center requires an internet connection to request https://update.sonarsource.org 195 | # It is enabled by default. 196 | sonar_updatecenter_activate: true 197 | 198 | # HTTP proxy (default none) 199 | http_proxy_host: "" 200 | http_proxy_port: "" 201 | # HTTPS proxy (defaults are values of http.proxyHost and http.proxyPort) 202 | https_proxy_host: "" 203 | https_proxy_port: "" 204 | 205 | # NT domain name if NTLM proxy is used 206 | http_auth_ntlm_domain: "" 207 | 208 | # SOCKS proxy (default none) 209 | socks_proxy_host: "" 210 | socks_proxy_port: "" 211 | 212 | # Proxy authentication (used for HTTP, HTTPS and SOCKS proxies) 213 | http_proxy_user: "" 214 | http_proxy_password: "" 215 | 216 | #-------------------------------------------------------------------------------------------------- 217 | # LOGGING 218 | 219 | # Level of logs. Supported values are INFO(default), DEBUG and TRACE (DEBUG + SQL + ES requests) 220 | sonar_log_level: "INFO" 221 | 222 | # Rolling policy of log files 223 | # - based on time if value starts with "time:", for example by day ("time:yyyy-MM-dd") 224 | # or by month ("time:yyyy-MM") 225 | # - based on size if value starts with "size:", for example "size:10MB" 226 | # - disabled if value is "none". That needs logs to be managed by an external system like logrotate. 227 | sonar_log_rolling_policy: "time:yyyy-MM-dd" 228 | 229 | # Maximum number of files to keep if a rolling policy is enabled. 230 | # - maximum value is 20 on size rolling policy 231 | # - unlimited on time rolling policy. Set to zero to disable old file purging. 232 | sonar_log_max_files: 7 233 | 234 | # Access log is the list of all the HTTP requests received by server. If enabled, it is stored 235 | # in the file {sonar.path.logs}/access.log. This file follows the same rolling policy as for 236 | # sonar.log (see sonar.log.rollingPolicy and sonar.log.maxFiles). 237 | sonar_web_access_logs_enable: true 238 | 239 | # Format of access log. It is ignored if sonar.web.accessLogs.enable=false. Possible values are: 240 | # - "common" is the Common Log Format, shortcut to: %h %l %u %user %date "%r" %s %b 241 | # - "combined" is another format widely recognized, shortcut to: %h %l %u [%t] "%r" %s %b "%i{Referer}" "%i{User-Agent}" 242 | # - else a custom pattern. See http://logback.qos.ch/manual/layouts.html#AccessPatternLayout. 243 | # If SonarQube is behind a reverse proxy, then the following value allows to display the correct remote IP address: 244 | sonar_web_access_logs_pattern: "%i{X-Forwarded-For} %l %u [%t] \"%r\" %s %b \"%i{Referer}\" \"%i{User-Agent}\"" 245 | 246 | #-------------------------------------------------------------------------------------------------- 247 | # LDAP 248 | # Ldap configuration for ldap auth plugin 249 | # see https://docs.sonarqube.org/latest/instance-administration/delegated-auth/ for more details and description of properties 250 | # 251 | # Example: 252 | # sonar_ldap: 253 | # authenticator_downcase: false 254 | # url: 'ldap://your_ldap_url' 255 | # bind_dn: 'cn=sonaruser,o=example,o=com' 256 | # bind_password: 'MyBindPassword' 257 | # user_base_dn: 'o=users,o=example,o=com' 258 | # authentication: simple 259 | # realm: 'example.org' 260 | # context_factory_class: com.sun.jndi.ldap.LdapCtxFactory 261 | # start_tls: false 262 | # follow_referrals: true 263 | # user_base_dn: 'cn=users,dc=example,dc=org' 264 | # user_request: '(&(objectClass=inetOrgPerson)(uid={login}))' 265 | # user_real_name_attribute: 'cn' 266 | # user_email_attribute: 'mail' 267 | # group_base_dn: 'o=groups,o=example,o=com' 268 | # group_request: '(&(objectClass=groupOfNames)(member={dn}))' 269 | # group_id_attribute: 'sAMAccountName' 270 | # 271 | # default: undefined 272 | # sonar_ldap: 273 | 274 | #-------------------------------------------------------------------------------------------------- 275 | # OTHERS 276 | 277 | # Delay in seconds between processing of notification queue. Default is 60 seconds. 278 | sonar_notifications_delay: 60 279 | 280 | # Pass any custom Java properties to sonar.properties 281 | sonar_additional_properties: {} 282 | 283 | #-------------------------------------------------------------------------------------------------- 284 | # DEVELOPMENT - only for developers 285 | # The following properties MUST NOT be used in production environments. 286 | 287 | # Dev mode allows to reload web sources on changes and to restart server when new versions 288 | # of plugins are deployed. 289 | sonar_web_dev: false 290 | 291 | # Path to webapp sources for hot-reloading of Ruby on Rails, JS and CSS (only core, 292 | # plugins not supported). 293 | sonar_web_dev_sources: "" 294 | 295 | # Elasticsearch HTTP connector, for example for KOPF: 296 | # http://lmenezes.com/elasticsearch-kopf/?location=http://localhost:9010 297 | sonar_search_http_port: -1 298 | -------------------------------------------------------------------------------- /handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # handlers file for ansible-role-sonarqube/ 3 | - name: "restart SonarQube service" 4 | service: 5 | name: sonar 6 | state: restarted 7 | 8 | - name: "fail if expected sonar version not confirmed" 9 | fail: 10 | msg: Please check if 'Version' field of http://{{ inventory_hostname }}{{ sonar_web_context }} match to {{ sonar_version }} 11 | 12 | - name: "warn about post-upgrade steps" 13 | debug: 14 | msg: 15 | - "SonarQube version changed to {{ sonar_version }} but additional actions required from your side" 16 | - "Visit http://{{ inventory_hostname }}{{ sonar_web_context }}/setup to follow the post-upgrade procedure" 17 | -------------------------------------------------------------------------------- /meta/main.yml: -------------------------------------------------------------------------------- 1 | galaxy_info: 2 | author: lrk 3 | role_name: sonarqube 4 | description: "An Ansible Role that install SonarQube." 5 | license: "Apache License Version 2.0" 6 | 7 | min_ansible_version: 2.4 8 | 9 | platforms: 10 | - name: EL 11 | versions: 12 | - 7 13 | - name: Ubuntu 14 | versions: 15 | - Bionic 16 | - Xenial 17 | - name: Debian 18 | versions: 19 | - Stretch 20 | 21 | galaxy_tags: 22 | - 'centos' 23 | - 'development' 24 | - 'monitoring' 25 | - 'sonarqube' 26 | -------------------------------------------------------------------------------- /molecule/default/Dockerfile.j2: -------------------------------------------------------------------------------- 1 | # Molecule managed 2 | 3 | {% if item.registry is defined %} 4 | FROM {{ item.registry.url }}/{{ item.image }} 5 | {% else %} 6 | FROM {{ item.image }} 7 | {% endif %} 8 | 9 | {% if item.env is defined %} 10 | {% for var, value in item.env.items() %} 11 | {% if value %} 12 | ENV {{ var }} {{ value }} 13 | {% endif %} 14 | {% endfor %} 15 | {% endif %} 16 | 17 | RUN if [ $(command -v apt-get) ]; then apt-get update && apt-get install -y python sudo bash ca-certificates iproute2 && apt-get clean; \ 18 | elif [ $(command -v dnf) ]; then dnf makecache && dnf --assumeyes install python sudo python-devel python*-dnf bash iproute && dnf clean all; \ 19 | elif [ $(command -v yum) ]; then yum makecache fast && yum install -y python sudo yum-plugin-ovl bash iproute && sed -i 's/plugins=0/plugins=1/g' /etc/yum.conf && yum clean all; \ 20 | elif [ $(command -v zypper) ]; then zypper refresh && zypper install -y python sudo bash python-xml iproute2 && zypper clean -a; \ 21 | elif [ $(command -v apk) ]; then apk update && apk add --no-cache python sudo bash ca-certificates; \ 22 | elif [ $(command -v xbps-install) ]; then xbps-install -Syu && xbps-install -y python sudo bash ca-certificates iproute2 && xbps-remove -O; fi 23 | -------------------------------------------------------------------------------- /molecule/default/converge.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Converge 3 | hosts: all 4 | vars: 5 | sonar_version: 7.9.6 6 | sonar_plugins: 7 | - name: "sonar-l10n-pt" 8 | version: "6.4" 9 | commercial: false 10 | url: "https://github.com/felipebz/sonar-l10n-pt/releases/download/v6.4/sonar-l10n-pt-plugin-6.4.jar" 11 | - name: "sonar-html-plugin" 12 | version: "3.2.0.2082" 13 | commercial: false 14 | - name: "ansible" 15 | version: "2.4.0" 16 | marketplace: true 17 | pre_tasks: 18 | - name: install openjdk (redhat) 19 | package: 20 | name: java-11-openjdk 21 | state: present 22 | when: ansible_facts['os_family'] == "RedHat" 23 | - name: add backports repository 24 | apt_repository: 25 | repo: deb http://ftp.debian.org/debian stretch-backports main 26 | state: present 27 | update_cache: yes 28 | when: ansible_facts['os_family'] == "Debian" 29 | - name: install openjdk (debian) 30 | apt: 31 | name: openjdk-11-jdk 32 | state: present 33 | when: ansible_facts['os_family'] == "Debian" 34 | roles: 35 | - role: ansible-role-sonarqube 36 | -------------------------------------------------------------------------------- /molecule/default/molecule.yml: -------------------------------------------------------------------------------- 1 | --- 2 | dependency: 3 | name: galaxy 4 | driver: 5 | name: docker 6 | lint: | 7 | set -e 8 | yamllint . 9 | ansible-lint . 10 | flake8 11 | platforms: 12 | - name: instance 13 | image: "geerlingguy/docker-${MOLECULE_DISTRO:-centos7}-ansible:latest" 14 | command: ${MOLECULE_DOCKER_COMMAND:-""} 15 | tmpfs: 16 | - /run 17 | - /tmp 18 | volumes: 19 | - /sys/fs/cgroup:/sys/fs/cgroup:ro 20 | privileged: true 21 | pre_build_image: true 22 | provisioner: 23 | name: ansible 24 | lint: 25 | name: ansible-lint 26 | verifier: 27 | lint: 28 | name: flake8 29 | -------------------------------------------------------------------------------- /molecule/default/prepare.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Prepare 3 | hosts: all 4 | tasks: 5 | - name: "Ensure apt cache is up to date" 6 | apt: 7 | update_cache: yes 8 | when: ansible_distribution == 'Ubuntu' 9 | 10 | - name: "Install package dependencies" 11 | package: 12 | name: "{{ item }}" 13 | state: "present" 14 | with_items: 15 | - unzip 16 | -------------------------------------------------------------------------------- /molecule/default/side_effect.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # starts after idempotence stage 3 | - name: Side Effect 4 | hosts: all 5 | vars: 6 | sonar_version: 8.9.3.48735 7 | sonar_plugins: [] 8 | tasks: 9 | - name: "Start role again and apply upgrade to {{ sonar_version }}" 10 | include_role: 11 | name: ansible-role-sonarqube 12 | -------------------------------------------------------------------------------- /molecule/vagrant/molecule.yml: -------------------------------------------------------------------------------- 1 | --- 2 | dependency: 3 | name: galaxy 4 | driver: 5 | name: vagrant 6 | provider: 7 | name: virtualbox 8 | lint: | 9 | set -e 10 | yamllint . 11 | ansible-lint . 12 | flake8 13 | platforms: 14 | - name: molecule-sonarqube 15 | box: ${MOLECULE_DISTRO:-centos/7} 16 | memory: 2048 17 | cpus: 2 18 | provisioner: 19 | name: ansible 20 | ansible_args: 21 | - --become 22 | lint: 23 | name: ansible-lint 24 | playbooks: 25 | converge: ../default/converge.yml 26 | prepare: ../default/prepare.yml 27 | side_effect: ../default/side_effect.yml 28 | verifier: 29 | lint: 30 | name: flake8 31 | -------------------------------------------------------------------------------- /molecule/vagrant/requirements.txt: -------------------------------------------------------------------------------- 1 | yamllint 2 | ansible 3 | ansible-lint 4 | flake8 5 | molecule 6 | molecule-vagrant 7 | -------------------------------------------------------------------------------- /tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # tasks file for ansible-role-sonarqube/ 3 | 4 | - name: "Create SonarQube system group" 5 | group: 6 | name: "{{ sonar_group }}" 7 | state: present 8 | 9 | - name: "Create SonarQube system user" 10 | user: 11 | name: "{{ sonar_user }}" 12 | group: "{{ sonar_group }}" 13 | createhome: no 14 | shell: "/sbin/nologin" 15 | comment: "SonarQube System user" 16 | state: present 17 | 18 | - name: "Create SonarQube directories" 19 | file: 20 | path: "{{ item }}" 21 | state: directory 22 | owner: "{{ sonar_user }}" 23 | group: "{{ sonar_group }}" 24 | mode: "u=rwx,g=rx,o=" 25 | with_items: 26 | - "{{ sonar_install_directory }}" 27 | - "{{ sonar_logs_dir }}" 28 | - "{{ sonar_data_dir }}" 29 | - "{{ sonar_temp_dir }}" 30 | 31 | - name: "set max_map_count value (required by elasticsearch)" 32 | sysctl: 33 | name: vm.max_map_count 34 | value: 262144 35 | state: present 36 | 37 | - name: "Ensure JAVA is installed" 38 | command: "java -version" 39 | register: prereq_java 40 | changed_when: false 41 | 42 | - name: "Fail if JAVA is not available" 43 | fail: 44 | msg: "JAVA is not installed or configured" 45 | when: not prereq_java.rc == 0 46 | 47 | - name: "Execute Debian specific tasks" 48 | include_tasks: setup_debian.yml 49 | when: ansible_os_family == 'Debian' 50 | 51 | - include_tasks: setup_prepare.yml 52 | 53 | - include_tasks: setup_sonarqube.yml 54 | 55 | - name: "install plugins" 56 | include_tasks: setup_plugin.yml 57 | with_items: "{{ sonar_plugins }}" 58 | loop_control: 59 | loop_var: "sonar_cplugin" 60 | 61 | - name: "flush handlers" 62 | meta: flush_handlers 63 | 64 | - name: "Ensure target version matches" 65 | uri: 66 | url: "http://{{ sonar_web_host }}:{{ sonar_web_port }}{{ sonar_web_context }}/api/server/version" 67 | method: GET 68 | return_content: yes 69 | register: api_check_version 70 | until: api_check_version.status == 200 71 | retries: 60 72 | delay: 5 73 | check_mode: no # uri module not support check mode (at least in Ansible 2.10) 74 | changed_when: sonar_version | string not in api_check_version.content 75 | notify: fail if expected sonar version not confirmed 76 | ignore_errors: "{{ ansible_check_mode }}" 77 | -------------------------------------------------------------------------------- /tasks/setup_debian.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: "Ensure required packages are installed" 3 | package: 4 | name: "{{ item }}" 5 | state: "present" 6 | with_items: 7 | - procps 8 | -------------------------------------------------------------------------------- /tasks/setup_plugin.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: "install plugin from binaries.sonarsource.com" 3 | include: setup_plugin_binaries.yml 4 | when: not sonar_cplugin.get('marketplace', false)|bool 5 | 6 | - name: "install plugin from updates.sonarsource.com" 7 | include: setup_plugin_marketplace.yml 8 | when: sonar_cplugin.get('marketplace', false)|bool 9 | 10 | - name: "{{ sonar_cplugin.name }} | Download current plugin" 11 | get_url: 12 | url: "{{ cplugin_url }}" 13 | dest: "{{ __sonar_plugin_home }}" 14 | owner: "{{ sonar_user }}" 15 | group: "{{ sonar_group }}" 16 | mode: "0644" 17 | retries: 5 18 | delay: 10 19 | notify: 20 | - "restart SonarQube service" 21 | -------------------------------------------------------------------------------- /tasks/setup_plugin_binaries.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: "{{ sonar_cplugin.name }} | Set current plugin's jar filename" 3 | set_fact: 4 | cplugin_fname: "{{ sonar_cplugin.name }}-{{ sonar_cplugin.version }}.jar" 5 | 6 | - name: "{{ sonar_cplugin.name }} | Set current plugins's custom download URL if available" 7 | set_fact: 8 | cplugin_url: "{{ sonar_cplugin.url }}" 9 | when: sonar_cplugin.url is defined and sonar_cplugin.url | length > 0 10 | 11 | - name: "{{ sonar_cplugin.name }} | Set current plugins's default download URL no custom one" 12 | set_fact: 13 | cplugin_url: "{{ sonar_cplugin.commercial | ternary(sonar_commercial_plugin_baseurl,sonar_plugin_baseurl) }}/{{ sonar_cplugin.name }}/{{ cplugin_fname }}" 14 | when: cplugin_url is not defined or cplugin_url | length <= 0 15 | -------------------------------------------------------------------------------- /tasks/setup_plugin_marketplace.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: "set plugin json url" 3 | set_fact: 4 | plugin_url: "{{ __sonar_marketplace_url }}/{{ sonar_cplugin.name }}.json" 5 | 6 | - name: "get plugin json for {{ sonar_cplugin.name }}" 7 | uri: 8 | url: "{{ plugin_url }}" 9 | method: GET 10 | return_content: yes 11 | status_code: 200 12 | body_format: json 13 | register: result 14 | 15 | - name: "extract plugin info" 16 | set_fact: 17 | plugin_info: "{{ result['content'] | from_json }}" 18 | 19 | - name: "check version" 20 | assert: 21 | that: 22 | - "'versions' in plugin_info" 23 | - "sonar_cplugin.version in plugin_info['versions']|map(attribute='version')|list" 24 | msg: "{{ sonar_cplugin.name }} plugin version '{{ sonar_cplugin.version }}' doesn't exist in {{ plugin_url }}" 25 | 26 | - name: "set download url" 27 | set_fact: 28 | cplugin_url: "{{ (plugin_info['versions']|selectattr('version','equalto',sonar_cplugin.version))[0]['downloadURL'] }}" 29 | -------------------------------------------------------------------------------- /tasks/setup_prepare.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: "Overwrite SonarQube download url" 4 | set_fact: 5 | sonar_download_url: "{{ __sonar_download_url }}" 6 | when: sonar_download_url is not defined 7 | 8 | - name: "Overwrite SonarQube plugin base url" 9 | set_fact: 10 | sonar_plugin_baseurl: "{{ __sonar_plugin_baseurl }}" 11 | when: sonar_plugin_baseurl is not defined 12 | 13 | - name: "Overwrite SonarQube commercial plugin base url" 14 | set_fact: 15 | sonar_commercial_plugin_baseurl: "{{ __sonar_commercial_plugin_baseurl }}" 16 | when: sonar_commercial_plugin_baseurl is not defined 17 | -------------------------------------------------------------------------------- /tasks/setup_sonarqube.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: "Check if SonarQube binary exists" 4 | stat: 5 | path: "{{ sonar_daemon_dir }}/sonar.sh" 6 | register: sonar_binary_stat 7 | 8 | - block: 9 | - name: "Download SonarQube binaries" 10 | get_url: 11 | url: "{{ sonar_download_url }}" 12 | dest: "/tmp/{{ __sonar_archive }}" 13 | retries: 5 14 | delay: 10 15 | 16 | - name: "Expand SonarQube binaries" 17 | unarchive: 18 | src: "/tmp/{{ __sonar_archive }}" 19 | dest: "{{ sonar_install_directory }}" 20 | owner: "{{ sonar_user }}" 21 | group: "{{ sonar_group }}" 22 | copy: no 23 | 24 | - name: "Remove SonarQube archive" 25 | file: 26 | path: "/tmp/{{ __sonar_archive }}" 27 | state: absent 28 | 29 | - name: "Collect the list of services to check if sonar.service exists" 30 | service_facts: 31 | 32 | - name: "Stop service before upgrade" 33 | service: 34 | name: sonar 35 | state: stopped 36 | when: '"sonar.service" in ansible_facts.services' 37 | notify: warn about post-upgrade steps 38 | 39 | when: not sonar_binary_stat.stat.exists 40 | 41 | - name: "Ensure SonarQube as init script for service management" 42 | file: 43 | src: "{{ sonar_daemon_dir }}/sonar.sh" 44 | dest: /etc/init.d/sonar 45 | state: link 46 | when: "ansible_service_mgr != 'systemd'" 47 | 48 | - name: "Copy SonarQube systemd unit file into place (for systemd systems)." 49 | template: 50 | src: sonar.service.j2 51 | dest: /etc/systemd/system/sonar.service 52 | owner: root 53 | group: root 54 | mode: 0755 55 | register: systemd_service 56 | when: "ansible_service_mgr == 'systemd'" 57 | 58 | - name: Force systemd to reread configs 59 | systemd: 60 | daemon_reload: yes 61 | tags: skip_ansible_lint 62 | when: systemd_service is defined and systemd_service.changed 63 | 64 | - name: "Ensure SonarQube is running and set to start on boot." 65 | service: 66 | name: sonar 67 | state: started 68 | enabled: yes 69 | 70 | - name: "Ensure SonarQube files permissions" 71 | file: 72 | path: "{{ sonar_install_directory }}" 73 | state: directory 74 | recurse: yes 75 | owner: "{{ sonar_user }}" 76 | group: "{{ sonar_group }}" 77 | mode: "o-w" 78 | 79 | - name: "Ensure SonarQube configuration" 80 | template: 81 | src: "sonar.properties.j2" 82 | dest: "{{ sonar_conf_dir }}/sonar.properties" 83 | owner: "{{ sonar_user }}" 84 | group: "{{ sonar_group }}" 85 | mode: "u=rw,g=,o=" 86 | no_log: true 87 | notify: 88 | - "restart SonarQube service" 89 | -------------------------------------------------------------------------------- /templates/sonar.properties.j2: -------------------------------------------------------------------------------- 1 | # Property values can: 2 | # - reference an environment variable, for example sonar.jdbc.url= ${env:SONAR_JDBC_URL} 3 | # - be encrypted. See http://redirect.sonarsource.com/doc/settings-encryption.html 4 | 5 | #-------------------------------------------------------------------------------------------------- 6 | # DATABASE 7 | 8 | {% if sonar_db_embedded %} 9 | sonar.embeddedDatabase.port={{ sonar_db_embedded_port | default('9092') }} 10 | {% else %} 11 | sonar.jdbc.username={{ sonar_db_user }} 12 | sonar.jdbc.password={{ sonar_db_pass }} 13 | sonar.jdbc.url={{ sonar_jdbc_url }} 14 | {% endif %} 15 | 16 | sonar.jdbc.maxActive={{ sonar_jdbc_maxactive | default('60') }} 17 | sonar.jdbc.maxIdle={{ sonar_jdbc_maxidle | default('5') }} 18 | sonar.jdbc.minIdle={{ sonar_jdbc_minidle | default('2') }} 19 | sonar.jdbc.maxWait={{ sonar_jdbc_maxwait | default('5000') }} 20 | 21 | sonar.jdbc.minEvictableIdleTimeMillis={{ sonar_jdbc_min_evictable_idle_time_millis | default('600000') }} 22 | sonar.jdbc.timeBetweenEvictionRunsMillis={{ sonar_jdbc_time_between_eviction_runs_millis | default('30000') }} 23 | 24 | #-------------------------------------------------------------------------------------------------- 25 | # WEB SERVER 26 | 27 | {% if (sonar_web_java_opts is defined) and (sonar_web_java_opts | length > 0) %} 28 | sonar.web.javaOpts={{ sonar_web_java_opts }} 29 | {% endif %} 30 | {% if (sonar_web_java_additional_opts is defined) and (sonar_web_java_additional_opts | length > 0) %} 31 | sonar.web.javaAdditionalOpts={{ sonar_web_java_additional_opts | default('') }} 32 | {% endif %} 33 | sonar.web.host={{ sonar_web_host | default('0.0.0.0') }} 34 | {% if (sonar_web_context is defined) and (sonar_web_context | length > 0) %} 35 | sonar.web.context={{ sonar_web_context }} 36 | {% endif %} 37 | sonar.web.port={{ sonar_web_port | default('9000') }} 38 | sonar.web.http.maxThreads={{ sonar_web_http_max_threads | default('50') }} 39 | sonar.web.http.minThreads={{ sonar_web_http_min_threads | default('5') }} 40 | sonar.web.http.acceptCount={{ sonar_web_http_accept_count | default('25') }} 41 | sonar.ajp.port={{ sonar_ajp_port | default('-1') }} 42 | 43 | 44 | {%- if (sonar_ldap is defined) %} 45 | #-------------------------------------------------------------------------------------------------- 46 | # LDAP AUTH 47 | sonar.security.realm=LDAP 48 | sonar.authenticator.downcase={{ sonar_ldap.authenticator_downcase | default('false') }} 49 | ldap.url={{ sonar_ldap.url | mandatory }} 50 | {% if (sonar_ldap.bind_dn is defined) and (sonar_ldap.bind_dn | length > 0 ) %} 51 | ldap.bindDn={{ sonar_ldap.bind_dn }} 52 | {% endif %} 53 | {% if (sonar_ldap.bind_password is defined) and (sonar_ldap.bind_password | length > 0 ) %} 54 | ldap.bindPassword={{ sonar_ldap.bind_password }} 55 | {% endif %} 56 | ldap.authentication={{ sonar_ldap.authentication | default('simple') }} 57 | {% if ( sonar_ldap.realm is defined) and (sonar_ldap.realm | length > 0 ) %} 58 | ldap.security.realm={{ sonar_ldap.realm }} 59 | {% endif %} 60 | ldap.contextFactoryClass={{ sonar_ldap.context_factory_class | default('com.sun.jndi.ldap.LdapCtxFactory') }} 61 | ldap.StartTLS={{ sonar_ldap.start_tls | default('false') }} 62 | ldap.followReferrals={{ sonar_ldap.follow_referrals | default('true') }} 63 | ldap.user.baseDn={{ sonar_ldap.user_base_dn | mandatory }} 64 | ldap.user.request={{ sonar_ldap.user_request | default('(&(objectClass=inetOrgPerson)(uid={login}))') }} 65 | ldap.user.realNameAttribute={{ sonar_ldap.user_real_name_attribute | default('cn') }} 66 | ldap.user.emailAttribute={{ sonar_ldap.user_email_attribute | default('mail') }} 67 | {% if (sonar_ldap.group_base_dn is defined) and (sonar_ldap.group_base_dn | length > 0 ) %} 68 | ldap.group.baseDn={{ sonar_ldap.group_base_dn }} 69 | {% endif %} 70 | ldap.group.request={{ sonar_ldap.group_request | default('(&(objectClass=groupOfUniqueNames)(uniqueMember={dn}))') }} 71 | ldap.group.idAttribute={{ sonar_ldap.group_id_attribute | default('cn') }} 72 | {%- endif %} 73 | 74 | #-------------------------------------------------------------------------------------------------- 75 | # COMPUTE ENGINE 76 | 77 | {% if (sonar_ce_java_opts is defined) and (sonar_ce_java_opts | length > 0) %} 78 | sonar.ce.javaOpts={{ sonar_ce_java_opts }} 79 | {% endif %} 80 | {% if (sonar_ce_java_additional_opts is defined) and (sonar_ce_java_additional_opts | length > 0) %} 81 | sonar.ce.javaAdditionalOpts={{ sonar_ce_java_additional_opts }} 82 | {% endif %} 83 | sonar.ce.workerCount={{ sonar_ce_worker_count | default('1') }} 84 | 85 | #-------------------------------------------------------------------------------------------------- 86 | # ELASTICSEARCH 87 | 88 | sonar.search.javaOpts={{ sonar_search_java_opts | default('-Xmx1G -Xms1G -Xss1m -Djava.net.preferIPv4Stack=true -XX:CMSInitiatingOccupancyFraction=75 -XX:+UseCMSInitiatingOccupancyOnly -XX:+HeapDumpOnOutOfMemoryError', true) }} 89 | sonar.search.javaAdditionalOpts={{ sonar_search_java_additional_opts | default('') }} 90 | sonar.search.port={{ sonar_search_port | default('9001') }} 91 | sonar.search.host={{ sonar_search_host | default('127.0.0.1') }} 92 | 93 | 94 | #-------------------------------------------------------------------------------------------------- 95 | # UPDATE CENTER 96 | 97 | sonar.updatecenter.activate={{ sonar_updatecenter_activate | default('true') | lower }} 98 | 99 | {% if (http_proxy_host is defined) and (http_proxy_host | length > 0) %} 100 | http.proxyHost={{ http_proxy_host }} 101 | {% endif %} 102 | {% if (http_proxy_port is defined) and (http_proxy_port | int > 0) %} 103 | http.proxyPort={{ http_proxy_port }} 104 | {% endif %} 105 | {% if (https_proxy_host is defined) and (https_proxy_host | length > 0) %} 106 | https.proxyHost={{ https_proxy_host }} 107 | {% endif %} 108 | {% if (https_proxy_port is defined) and (https_proxy_port | int > 0) %} 109 | https.proxyPort={{ https_proxy_port }} 110 | {% endif %} 111 | {% if (http_auth_ntlm_domain is defined) and (http_auth_ntlm_domain | length > 0) %} 112 | http.auth.ntlm.domain={{ http_auth_ntlm_domain }} 113 | {% endif %} 114 | {% if (socks_proxy_host is defined) and (socks_proxy_host | length > 0) %} 115 | socksProxyHost={{ socks_proxy_host }} 116 | {% endif %} 117 | {% if (socks_proxy_port is defined) and (socks_proxy_port | int > 0) %} 118 | socksProxyPort={{ socks_proxy_port }} 119 | {% endif %} 120 | # Proxy authentication (used for HTTP, HTTPS and SOCKS proxies) 121 | {% if (http_proxy_user is defined) and (http_proxy_user | length > 0) %} 122 | http.proxyUser={{ http_proxy_user }} 123 | {% endif %} 124 | {% if (http_proxy_password is defined) and (http_proxy_password | length > 0) %} 125 | http.proxyPassword={{ http_proxy_password }} 126 | {% endif %} 127 | 128 | #-------------------------------------------------------------------------------------------------- 129 | # LOGGING 130 | 131 | sonar.log.level={{ sonar_log_level | default('INFO') }} 132 | sonar.path.logs={{ sonar_logs_dir | default('logs') }} 133 | sonar.log.rollingPolicy={{ sonar_log_rolling_policy | default('time:yyyy-MM-dd') }} 134 | sonar.log.maxFiles={{ sonar_log_max_files | default('7') }} 135 | sonar.web.access_logs.enable={{ sonar_web_access_logs_enable | default('true') | lower }} 136 | sonar.web.accessLogs.pattern={{ sonar_web_access_logs_pattern | default('combined')}} 137 | 138 | 139 | #-------------------------------------------------------------------------------------------------- 140 | # OTHERS 141 | 142 | # Delay in seconds between processing of notification queue. Default is 60 seconds. 143 | sonar.notifications.delay={{ sonar_notifications_delay | default('60') }} 144 | 145 | # Paths to persistent data files (embedded database and search index) and temporary files. 146 | # Can be absolute or relative to installation directory. 147 | # Defaults are respectively /data and /temp 148 | sonar.path.data={{ sonar_data_dir | default('data') }} 149 | sonar.path.temp={{ sonar_temp_dir | default('temp') }} 150 | 151 | {% if sonar_additional_properties is defined %} 152 | #-------------------------------------------------------------------------------------------------- 153 | # ADDITIONAL PROPERIES 154 | {% for p in sonar_additional_properties | dict2items %} 155 | {{ p.key }} = {{ p.value }} 156 | {% endfor %} 157 | {% endif %} 158 | 159 | #-------------------------------------------------------------------------------------------------- 160 | # DEVELOPMENT - only for developers 161 | # The following properties MUST NOT be used in production environments. 162 | {% if (sonar_web_dev is defined) and (sonar_web_dev != False) %} 163 | sonar_web_dev={{ sonar_web_dev | lower}} 164 | {% endif %} 165 | {% if (sonar_web_dev_sources is defined) and (sonar_web_dev_sources | length > 0) %} 166 | sonar.web.dev.sources={{ sonar_web_dev_sources }} 167 | {% endif %} 168 | {% if (sonar_search_http_port is defined) and (sonar_search_http_port | int > 0) %} 169 | sonar.search.httpPort={{ sonar_search_http_port }} 170 | {% endif %} 171 | -------------------------------------------------------------------------------- /templates/sonar.service.j2: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=SonarQube {{ sonar_version }} service 3 | Requires=network.target 4 | After=network.target network-online.target 5 | Wants=network-online.target 6 | 7 | [Service] 8 | Type=forking 9 | ExecStart={{ sonar_daemon_dir }}/sonar.sh start 10 | ExecStop={{ sonar_daemon_dir }}/sonar.sh stop 11 | ExecReload={{ sonar_daemon_dir }}/sonar.sh restart 12 | Restart=on-failure 13 | RestartSec=10 14 | PIDFile={{ sonar_daemon_dir }}/SonarQube.pid 15 | User={{ sonar_user }} 16 | Group={{ sonar_group }} 17 | LimitNOFILE={{ sonar_limitnofile }} 18 | 19 | [Install] 20 | WantedBy=multi-user.target 21 | -------------------------------------------------------------------------------- /vars/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # vars file for ansible-role-sonarqube/ 3 | __sonarsource_url: "https://binaries.sonarsource.com" 4 | __sonar_marketplace_url: "https://update.sonarsource.org" 5 | __sonar_distribution_url: "{{ __sonarsource_url }}/Distribution" 6 | __sonar_archive: "sonarqube-{{ sonar_version }}.zip" 7 | __sonar_download_url: "{{ __sonar_distribution_url }}/sonarqube/{{ __sonar_archive }}" 8 | __sonar_plugin_home: "{{ sonar_base_dir }}/extensions/plugins" 9 | __sonar_plugin_baseurl: "{{ __sonar_distribution_url }}" 10 | __sonar_commercial_plugin_baseurl: "{{ __sonarsource_url }}/CommercialDistribution" 11 | --------------------------------------------------------------------------------