├── .editorconfig ├── .gitignore ├── LICENSE ├── README.md ├── Vagrantfile ├── files ├── certs │ └── .gitkeep └── cf-template │ └── hackathon.json ├── github-cleanup.yml ├── github-prepare.yml ├── hackathons ├── 2015-02-23-4financeit-prague.yml ├── 2015-03-21-jug-lodz.yml ├── 2015-08-28-codepot-warszawa.yml ├── 2015-09-08-wjug-warszawa.yml ├── default.yml ├── docs │ ├── 2015-02-23-4financeit-prague.md │ ├── 2015-03-21-jug-lodz.md │ ├── 2015-08-28-codepot-warszawa.md │ ├── 2015-09-08-wjug-warszawa.md │ ├── microhackathon-test.md │ └── uservices-hackathon.md ├── microhackathon-test.yml └── uservices-hackathon.yml ├── roles ├── apache │ ├── defaults │ │ └── main.yml │ ├── files │ │ └── allow-srv.conf │ ├── handlers │ │ └── main.yml │ └── tasks │ │ └── main.yml ├── common │ ├── defaults │ │ └── main.yml │ └── tasks │ │ └── main.yml ├── deploy │ ├── defaults │ │ └── main.yml │ └── tasks │ │ └── main.yml ├── elasticsearch │ ├── defaults │ │ └── main.yml │ ├── handlers │ │ └── main.yml │ └── tasks │ │ └── main.yml ├── github_repo │ ├── defaults │ │ └── main.yml │ └── tasks │ │ └── main.yml ├── github_repo_docs │ ├── defaults │ │ └── main.yml │ ├── tasks │ │ └── main.yml │ └── templates │ │ └── _config.yml.j2 ├── github_repo_microservice │ ├── defaults │ │ └── main.yml │ ├── tasks │ │ └── main.yml │ └── templates │ │ ├── application.yaml.j2 │ │ └── microservice.json.j2 ├── github_repo_properties │ ├── defaults │ │ └── main.yml │ ├── tasks │ │ └── main.yml │ └── templates │ │ ├── application.yaml.j2 │ │ └── global.yaml.j2 ├── grafana │ ├── defaults │ │ └── main.yml │ ├── tasks │ │ └── main.yml │ └── templates │ │ ├── grafana-vhost.j2 │ │ └── grafana.js.j2 ├── graphite │ ├── defaults │ │ └── main.yml │ ├── handlers │ │ └── main.yml │ ├── tasks │ │ └── main.yml │ ├── templates │ │ └── graphite-vhost.j2 │ └── vars │ │ └── main.yml ├── hystrix_dashboard │ ├── defaults │ │ └── main.yml │ ├── handlers │ │ └── main.yml │ ├── tasks │ │ └── main.yml │ ├── templates │ │ └── server.xml.j2 │ └── vars │ │ └── main.yml ├── jenkins │ ├── .travis.yml │ ├── README.md │ ├── defaults │ │ └── main.yml │ ├── handlers │ │ └── main.yml │ ├── meta │ │ └── main.yml │ ├── tasks │ │ ├── main.yml │ │ ├── plugins.yml │ │ ├── setup-Debian.yml │ │ └── setup-RedHat.yml │ └── tests │ │ ├── inventory │ │ └── test.yml ├── jenkins_seed_job │ ├── defaults │ │ └── main.yml │ ├── tasks │ │ └── main.yml │ └── templates │ │ └── job.xml.j2 ├── kibana │ ├── defaults │ │ └── main.yml │ ├── tasks │ │ └── main.yml │ └── templates │ │ └── kibana-apache-site.j2 ├── logstash │ ├── defaults │ │ └── main.yml │ ├── handlers │ │ └── main.yml │ ├── tasks │ │ └── main.yml │ └── templates │ │ └── conf.d │ │ ├── 01-lumberjack-input.conf.j2 │ │ ├── 11-java-apps.conf.j2 │ │ └── 21-es-output.conf.j2 ├── logstash_forwarder │ ├── defaults │ │ └── main.yml │ ├── handlers │ │ └── main.yml │ ├── tasks │ │ └── main.yml │ └── templates │ │ └── logstash-forwarder.conf.j2 ├── mongodb │ └── tasks │ │ └── main.yml ├── oracle_jdk │ ├── defaults │ │ └── main.yml │ ├── tasks │ │ └── main.yml │ └── vars │ │ └── main.yml ├── rundeck │ ├── defaults │ │ └── main.yml │ ├── files │ │ └── aclpolicies │ │ │ ├── admin.aclpolicy │ │ │ └── apitoken.aclpolicy │ ├── handlers │ │ └── main.yml │ ├── tasks │ │ ├── install.yml │ │ ├── main.yml │ │ └── projects.yml │ ├── templates │ │ ├── framework.properties.j2 │ │ ├── jaas-loginmodule.conf.j2 │ │ ├── log4j.properties.j2 │ │ ├── profile.j2 │ │ ├── project.properties.j2 │ │ ├── realm.properties.j2 │ │ └── rundeck-config.properties.j2 │ └── vars │ │ └── main.yml ├── seyren │ ├── defaults │ │ └── main.yml │ ├── handlers │ │ └── main.yml │ ├── meta │ │ └── main.yml │ ├── tasks │ │ └── main.yml │ └── templates │ │ └── seyren.service.j2 ├── sonatype-nexus │ ├── README.md │ ├── defaults │ │ └── main.yml │ ├── files │ │ └── nexus.init │ ├── handlers │ │ └── main.yml │ ├── tasks │ │ ├── configure.yml │ │ ├── download.yml │ │ ├── main.yml │ │ ├── nginx.yml │ │ ├── openjdk.yml │ │ └── startup.yml │ ├── templates │ │ └── nginx.conf.j2 │ └── vars │ │ └── main.yml └── zookeeper │ ├── defaults │ └── main.yml │ ├── handlers │ └── main.yml │ ├── tasks │ ├── exhibitor.yml │ ├── main.yml │ └── zookeeper.yml │ ├── templates │ ├── exhibitor.properties.j2 │ └── exhibitor.service.j2 │ └── vars │ └── main.yml ├── scripts └── deploy-microservice.sh └── site.yml /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: http://EditorConfig.org 2 | 3 | # top-most EditorConfig file 4 | root = true 5 | 6 | [*] 7 | end_of_line = lf 8 | insert_final_newline = true 9 | 10 | [*.py] 11 | indent_style = space 12 | indent_size = 4 13 | 14 | [*.yml] 15 | indent_style = space 16 | indent_size = 2 17 | 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.key 2 | *.pem 3 | *.*~ 4 | .vagrant 5 | *.swp 6 | group_vars/secrets.yml 7 | inventory 8 | files/certs/* 9 | -------------------------------------------------------------------------------- /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-microservice-hackathon 2 | ============================== 3 | 4 | During the microservice hackathon we will need to provision: 5 | 6 | ## log monitoring (log server) 7 | 8 | - elasticsearch 9 | - redis 10 | - logstash 11 | - kibana 12 | 13 | ## metrics collecting (metrics server) 14 | 15 | - graphite 16 | - graphana 17 | 18 | ## microservice related stuff (app server) 19 | 20 | - zookeeper 21 | - logstash-forwarder 22 | - rundeck 23 | 24 | ## deployment related infrastructure: (deploy server) 25 | 26 | - nexus 27 | 28 | # Playbooks: 29 | 30 | ## Log monitoring 31 | 32 | After provisioning just access __http://kibana.warsjawa.uservices.pl__. 33 | 34 | ### Provisioning 35 | 36 | ``` 37 | ansible-playbook -i inventory site.yml -vvvv --limit loggers 38 | ``` 39 | 40 | ## Metrics monitoring 41 | 42 | After provisioning you can access 43 | 44 | - __graphite__ at __http://graphite.warsjawa.uservices.pl__ 45 | - __graphana__ at __http://grafana.warsjawa.uservices.pl__ 46 | 47 | ### Provisioning 48 | 49 | ``` 50 | ansible-playbook -i inventory site.yml -vvvv --limit graphite 51 | ``` 52 | 53 | ## Applications 54 | 55 | ``` 56 | ansible-playbook -i inventory site.yml -vvvv --limit apps 57 | ``` 58 | 59 | ### JDK8 60 | 61 | Oracle JDK 8u5. 62 | 63 | ### logstash forwarder 64 | 65 | Installed as a service that logs to syslog. 66 | 67 | ## Deployment - nexus 68 | 69 | After provisioning you can access Nexus at __http://nexus.warsjawa.uservices.pl:8081/nexus/#welcome__ 70 | 71 | ### Installation 72 | 73 | ``` 74 | ansible-playbook -i inventory site.yml -vvvv --limit loggers 75 | ``` 76 | 77 | Playbook origins 78 | ================ 79 | 80 | - ELK stack - https://github.com/valentinogagliardi/ansible-logstash 81 | - Oracle JDK - https://github.com/wybczu/ansible_oracle_jdk 82 | - logstash forwarder - https://github.com/WeAreFarmGeek/ansible-logstash-forwarder 83 | - nexus - https://github.com/marcingrzejszczak/ansible-sonatype-nexus 84 | -------------------------------------------------------------------------------- /Vagrantfile: -------------------------------------------------------------------------------- 1 | # -*- mode: ruby -*- 2 | # vim:ft=ruby:ts=2:et:sw=2 3 | 4 | require 'yaml' 5 | 6 | Vagrant.require_version ">= 1.7.2" 7 | 8 | default_settings = YAML.load_file(File.expand_path(File.join(File.dirname(__FILE__), "hackathons/default.yml"))) 9 | domain = default_settings['domain'] 10 | 11 | plugins = [ 12 | 'vagrant-hostmanager', 13 | ] 14 | 15 | plugins.each do |plugin| 16 | if !Vagrant.has_plugin?(plugin) 17 | puts "Please execute: vagrant plugin install #{plugin}" 18 | exit 1 19 | end 20 | end 21 | 22 | VAGRANTFILE_API_VERSION = "2" 23 | 24 | Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| 25 | 26 | config.hostmanager.enabled = true 27 | config.hostmanager.manage_host = false 28 | config.hostmanager.ignore_private_ip = false 29 | config.hostmanager.include_offline = true 30 | 31 | config.vm.box = "debian/jessie64" 32 | 33 | config.vm.provision "ansible" do |ansible| 34 | ansible.playbook = "site.yml" 35 | ansible.extra_vars = { 36 | 'is_vagrant' => 1, 37 | } 38 | end 39 | 40 | config.vm.define "monitoring" do |config| 41 | config.vm.host_name = "monitoring.#{domain}" 42 | config.vm.network "private_network", ip: "10.11.12.10" 43 | config.hostmanager.aliases = [ 44 | "graphite.#{domain}", 45 | "grafana.#{domain}", 46 | "kibana.#{domain}", 47 | "elasticsearch.#{domain}", 48 | ] 49 | end 50 | 51 | config.vm.define "apps" do |config| 52 | config.vm.host_name = "apps.#{domain}" 53 | config.vm.network "private_network", ip: "10.11.12.11" 54 | end 55 | 56 | config.vm.define "nexus" do |config| 57 | config.vm.host_name = "nexus.#{domain}" 58 | config.vm.network "private_network", ip: "10.11.12.13" 59 | end 60 | 61 | config.vm.define "jenkins" do |config| 62 | config.vm.host_name = "jenkins.#{domain}" 63 | config.vm.network "private_network", ip: "10.11.12.14" 64 | end 65 | 66 | config.vm.define "rundeck" do |config| 67 | config.vm.host_name = "rundeck.#{domain}" 68 | config.vm.network "private_network", ip: "10.11.12.15" 69 | end 70 | 71 | end 72 | -------------------------------------------------------------------------------- /files/certs/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microservice-hackathon/infrastructure/0aa687a095b84cb2490f894f681bd19de1355003/files/certs/.gitkeep -------------------------------------------------------------------------------- /files/cf-template/hackathon.json: -------------------------------------------------------------------------------- 1 | { 2 | 3 | "AWSTemplateFormatVersion" : "2010-09-09", 4 | 5 | "Description" : "Microhackathon template", 6 | 7 | "Parameters" : { 8 | 9 | "AmiId" : { 10 | "Type" : "String" 11 | }, 12 | 13 | "SecurityGroupId": { 14 | "Type" : "String" 15 | }, 16 | 17 | "KeyName" : { 18 | "Type" : "String" 19 | }, 20 | 21 | "SubnetId" : { 22 | "Type" : "String" 23 | }, 24 | 25 | "Domain" : { 26 | "Type" : "String" 27 | } 28 | 29 | }, 30 | 31 | "Resources" : { 32 | 33 | "monitoring" : { 34 | "Type" : "AWS::EC2::Instance", 35 | "Properties" : { 36 | "ImageId" : { "Ref" : "AmiId" }, 37 | "SecurityGroupIds" : [{ "Ref" : "SecurityGroupId" }], 38 | "SubnetId" : { "Ref" : "SubnetId" }, 39 | "KeyName" : { "Ref" : "KeyName" }, 40 | "InstanceType":"m3.large", 41 | "Tags":[ 42 | { 43 | "Key" : "Name", 44 | "Value" : { "Fn::Join" : [ "-", [ "monitoring", { "Ref" : "AWS::StackName" } ] ] } 45 | } 46 | ], 47 | "UserData": { "Fn::Base64" : { "Fn::Join" : ["\n", 48 | [ 49 | "#cloud-config", 50 | "hostname: monitoring", 51 | { "Fn::Join" : [".", 52 | ["fqdn: monitoring", { "Ref" : "Domain" }] 53 | ]}, 54 | "manage_etc_hosts: True", 55 | "resize_rootfs: True", 56 | "package_update: True", 57 | "package_upgrade: True" 58 | ] ] } 59 | }, 60 | "BlockDeviceMappings" : [ 61 | { 62 | "DeviceName" : "/dev/sda", 63 | "Ebs" : { 64 | "VolumeSize" : 50, 65 | "DeleteOnTermination" : true 66 | } 67 | } 68 | ] 69 | } 70 | }, 71 | 72 | "rundeck" : { 73 | "Type" : "AWS::EC2::Instance", 74 | "Properties" : { 75 | "ImageId" : { "Ref" : "AmiId" }, 76 | "SecurityGroupIds" : [{ "Ref" : "SecurityGroupId" }], 77 | "SubnetId" : { "Ref" : "SubnetId" }, 78 | "KeyName" : { "Ref" : "KeyName" }, 79 | "InstanceType":"m3.medium", 80 | "Tags":[ 81 | { 82 | "Key" : "Name", 83 | "Value" : { "Fn::Join" : [ "-", [ "rundeck", { "Ref" : "AWS::StackName" } ] ] } 84 | } 85 | ], 86 | "UserData": { "Fn::Base64" : { "Fn::Join" : ["\n", 87 | [ 88 | "#cloud-config", 89 | "hostname: rundeck", 90 | { "Fn::Join" : [".", 91 | ["fqdn: rundeck", { "Ref" : "Domain" }] 92 | ]}, 93 | "manage_etc_hosts: True", 94 | "resize_rootfs: True", 95 | "package_update: True", 96 | "package_upgrade: True" 97 | ] ] } 98 | }, 99 | "BlockDeviceMappings" : [ 100 | { 101 | "DeviceName" : "/dev/sda", 102 | "Ebs" : { 103 | "DeleteOnTermination" : true 104 | } 105 | } 106 | ] 107 | } 108 | }, 109 | 110 | "nexus" : { 111 | "Type" : "AWS::EC2::Instance", 112 | "Properties" : { 113 | "ImageId" : { "Ref" : "AmiId" }, 114 | "SecurityGroupIds" : [{ "Ref" : "SecurityGroupId" }], 115 | "SubnetId" : { "Ref" : "SubnetId" }, 116 | "KeyName" : { "Ref" : "KeyName" }, 117 | "InstanceType":"m3.medium", 118 | "Tags":[ 119 | { 120 | "Key" : "Name", 121 | "Value" : { "Fn::Join" : [ "-", [ "nexus", { "Ref" : "AWS::StackName" } ] ] } 122 | } 123 | ], 124 | "UserData": { "Fn::Base64" : { "Fn::Join" : ["\n", 125 | [ 126 | "#cloud-config", 127 | "hostname: nexus", 128 | { "Fn::Join" : [".", 129 | ["fqdn: nexus", { "Ref" : "Domain" }] 130 | ]}, 131 | "manage_etc_hosts: True", 132 | "resize_rootfs: True", 133 | "package_update: True", 134 | "package_upgrade: True" 135 | ] ] } 136 | }, 137 | "BlockDeviceMappings" : [ 138 | { 139 | "DeviceName" : "/dev/sda", 140 | "Ebs" : { 141 | "VolumeSize" : 350, 142 | "DeleteOnTermination" : true 143 | } 144 | } 145 | ] 146 | } 147 | }, 148 | 149 | "jenkins" : { 150 | "Type" : "AWS::EC2::Instance", 151 | "Properties" : { 152 | "ImageId" : { "Ref" : "AmiId" }, 153 | "SecurityGroupIds" : [{ "Ref" : "SecurityGroupId" }], 154 | "SubnetId" : { "Ref" : "SubnetId" }, 155 | "KeyName" : { "Ref" : "KeyName" }, 156 | "InstanceType":"m3.xlarge", 157 | "Tags":[ 158 | { 159 | "Key" : "Name", 160 | "Value" : { "Fn::Join" : [ "-", [ "jenkins", { "Ref" : "AWS::StackName" } ] ] } 161 | } 162 | ], 163 | "UserData": { "Fn::Base64" : { "Fn::Join" : ["\n", 164 | [ 165 | "#cloud-config", 166 | "hostname: jenkins", 167 | { "Fn::Join" : [".", 168 | ["fqdn: jenkins", { "Ref" : "Domain" }] 169 | ]}, 170 | "manage_etc_hosts: True", 171 | "resize_rootfs: True", 172 | "package_update: True", 173 | "package_upgrade: True" 174 | ] ] } 175 | }, 176 | "BlockDeviceMappings" : [ 177 | { 178 | "DeviceName" : "/dev/sda", 179 | "Ebs" : { 180 | "VolumeSize" : 200, 181 | "DeleteOnTermination" : true 182 | } 183 | } 184 | ] 185 | } 186 | }, 187 | 188 | "apps" : { 189 | "Type" : "AWS::EC2::Instance", 190 | "Properties" : { 191 | "ImageId" : { "Ref" : "AmiId" }, 192 | "SecurityGroupIds" : [{ "Ref" : "SecurityGroupId" }], 193 | "SubnetId" : { "Ref" : "SubnetId" }, 194 | "KeyName" : { "Ref" : "KeyName" }, 195 | "InstanceType":"m3.large", 196 | "Tags":[ 197 | { 198 | "Key" : "Name", 199 | "Value" : { "Fn::Join" : [ "-", [ "apps", { "Ref" : "AWS::StackName" } ] ] } 200 | } 201 | ], 202 | "UserData": { "Fn::Base64" : { "Fn::Join" : ["\n", 203 | [ 204 | "#cloud-config", 205 | "hostname: apps", 206 | { "Fn::Join" : [".", 207 | ["fqdn: apps", { "Ref" : "Domain" }] 208 | ]}, 209 | "manage_etc_hosts: True", 210 | "resize_rootfs: True", 211 | "package_update: True", 212 | "package_upgrade: True" 213 | ] ] } 214 | }, 215 | "BlockDeviceMappings" : [ 216 | { 217 | "DeviceName" : "/dev/sda", 218 | "Ebs" : { 219 | "VolumeSize" : 50, 220 | "DeleteOnTermination" : true 221 | } 222 | } 223 | ] 224 | } 225 | } 226 | 227 | }, 228 | 229 | "Outputs" : { 230 | "monitoring" : { 231 | "Value" : { "Fn::GetAtt" : [ "monitoring", "PrivateIp" ] } 232 | }, 233 | "rundeck" : { 234 | "Value" : { "Fn::GetAtt" : [ "rundeck", "PrivateIp" ] } 235 | }, 236 | "jenkins" : { 237 | "Value" : { "Fn::GetAtt" : [ "nexus", "PrivateIp" ] } 238 | }, 239 | "jenkins" : { 240 | "Value" : { "Fn::GetAtt" : [ "jenkins", "PrivateIp" ] } 241 | }, 242 | "apps" : { 243 | "Value" : { "Fn::GetAtt" : [ "apps", "PrivateIp" ] } 244 | } 245 | } 246 | } 247 | -------------------------------------------------------------------------------- /github-cleanup.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: cleanup github repositories 4 | hosts: localhost 5 | connection: local 6 | gather_facts: no 7 | vars_files: 8 | - hackathons/{{ hackathon_edition }}.yml 9 | - hackathons/default.yml 10 | tasks: 11 | - name: remove repos 12 | command: > 13 | curl -X "DELETE" -u {{ lookup('env', 'GH_USERNAME') }}:{{ lookup('env', 'GH_ACCESS_TOKEN') }} 14 | https://api.github.com/repos/{{ github_organization }}/{{ item.name }} 15 | with_items: "{{ projects }}" 16 | -------------------------------------------------------------------------------- /github-prepare.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: setup github repositories 4 | hosts: localhost 5 | connection: local 6 | gather_facts: no 7 | vars_files: 8 | - hackathons/{{ hackathon_edition }}.yml 9 | - hackathons/default.yml 10 | roles: 11 | - { 12 | role: github_repo, 13 | github_repo_projects: "{{ projects }}", 14 | github_repo_organization: "{{ github_organization }}", 15 | github_repo_user: "{{ lookup('env', 'GH_USERNAME') }}", 16 | github_repo_token: "{{ lookup('env', 'GH_ACCESS_TOKEN') }}" 17 | } 18 | - { 19 | role: github_repo, 20 | github_repo_projects: "{{ docs }}", 21 | github_repo_organization: "{{ github_organization }}", 22 | github_repo_user: "{{ lookup('env', 'GH_USERNAME') }}", 23 | github_repo_token: "{{ lookup('env', 'GH_ACCESS_TOKEN') }}" 24 | } 25 | - { 26 | role: github_repo, 27 | github_repo_projects: "{{ properties }}", 28 | github_repo_organization: "{{ github_organization }}", 29 | github_repo_user: "{{ lookup('env', 'GH_USERNAME') }}", 30 | github_repo_token: "{{ lookup('env', 'GH_ACCESS_TOKEN') }}" 31 | } 32 | - { 33 | role: github_repo_microservice, 34 | github_repo_microservice_projects: "{{ projects }}", 35 | github_repo_microservice_organization: "{{ github_organization }}", 36 | } 37 | - { 38 | role: github_repo_docs, 39 | github_repo_docs_organization: "{{ github_organization }}", 40 | github_repo_docs_projects: "{{ projects }}", 41 | github_repo_docs_tools: "{{ tools }}", 42 | } 43 | - { 44 | role: github_repo_properties, 45 | github_repo_properties_organization: "{{ github_organization }}", 46 | github_repo_properties_projects: "{{ projects }}", 47 | github_repo_properties_tools: "{{ tools }}", 48 | } 49 | -------------------------------------------------------------------------------- /hackathons/2015-02-23-4financeit-prague.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | domain: hackathon.dev.4finance.net 4 | github_organization: microhackathon-2015-02-Prague 5 | docs_title: "Microservice Hackathon - Prague 2015-02-23" 6 | 7 | docs: 8 | - name: "{{ github_organization }}.github.io" 9 | template: https://github.com/microservice-hackathon/docs-template.git 10 | template_version: master 11 | 12 | projects: 13 | 14 | - name: fraud-detection-service-pl 15 | port: 8053 16 | template: https://github.com/4finance/boot-microservice.git 17 | template_version: master 18 | 19 | - name: loan-application-service-pl 20 | port: 8054 21 | template: https://github.com/4finance/boot-microservice.git 22 | template_version: master 23 | 24 | - name: loan-application-decision-maker-pl 25 | port: 8055 26 | template: https://github.com/4finance/boot-microservice.git 27 | template_version: master 28 | 29 | - name: marketing-offer-generator-pl 30 | port: 8056 31 | template: https://github.com/4finance/boot-microservice.git 32 | template_version: master 33 | 34 | - name: reporting-service-pl 35 | port: 8057 36 | template: https://github.com/4finance/boot-microservice.git 37 | template_version: boot-microservice-gui 38 | 39 | - name: client-service-pl 40 | port: 8058 41 | template: https://github.com/4finance/boot-microservice.git 42 | template_version: boot-microservice-gui 43 | 44 | - name: ui-pl 45 | port: 8059 46 | template: https://github.com/4finance/boot-microservice.git 47 | template_version: boot-microservice-gui 48 | 49 | - name: fraud-detection-service-cz 50 | port: 9053 51 | template: https://github.com/4finance/boot-microservice.git 52 | template_version: master 53 | 54 | - name: loan-application-service-cz 55 | port: 9054 56 | template: https://github.com/4finance/boot-microservice.git 57 | template_version: master 58 | 59 | - name: loan-application-decision-maker-cz 60 | port: 9055 61 | template: https://github.com/4finance/boot-microservice.git 62 | template_version: master 63 | 64 | - name: marketing-offer-generator-cz 65 | port: 9056 66 | template: https://github.com/4finance/boot-microservice.git 67 | template_version: master 68 | 69 | - name: reporting-service-cz 70 | port: 9057 71 | template: https://github.com/4finance/boot-microservice.git 72 | template_version: boot-microservice-gui 73 | 74 | - name: client-service-cz 75 | port: 9058 76 | template: https://github.com/4finance/boot-microservice.git 77 | template_version: boot-microservice-gui 78 | 79 | - name: ui-cz 80 | port: 9059 81 | template: https://github.com/4finance/boot-microservice.git 82 | template_version: boot-microservice-gui 83 | 84 | attendees: 85 | - mdavidek 86 | - trehak1 87 | - najmanko 88 | - MadalinaBidilita 89 | - climbee 90 | - cbuleandra 91 | - skoky76 92 | - j-novak 93 | - stawron 94 | - me3x 95 | - ceyhunhan 96 | - lukooo 97 | - dstepanov 98 | - Jakub-Smrcka 99 | - lubsvo 100 | - thuryn 101 | - hnevkop 102 | - stepanovsky 103 | - danielmatteoni 104 | - mmarekpohl 105 | - mkurka 106 | - pafkaCz 107 | - smaragda 108 | - moiety 109 | - pirer 110 | - mmadron 111 | - cernya 112 | -------------------------------------------------------------------------------- /hackathons/2015-03-21-jug-lodz.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | domain: uservices.pl 4 | github_organization: microhackathon-2015-03-juglodz 5 | docs_title: "Microservice Hackathon - Łódź 2015-03-21" 6 | 7 | docs: 8 | - name: "{{ github_organization }}.github.io" 9 | template: https://github.com/microservice-hackathon/docs-template.git 10 | template_version: master 11 | 12 | projects: 13 | 14 | - name: ui-waw 15 | port: 8052 16 | template: https://github.com/4finance/boot-microservice.git 17 | template_version: boot-microservice-gui-without-node 18 | 19 | - name: fraud-detection-service-waw 20 | port: 8053 21 | template: https://github.com/4finance/boot-microservice.git 22 | template_version: master 23 | 24 | - name: loan-application-service-waw 25 | port: 8054 26 | template: https://github.com/4finance/boot-microservice.git 27 | template_version: master 28 | 29 | - name: loan-application-decision-maker-waw 30 | port: 8055 31 | template: https://github.com/4finance/boot-microservice.git 32 | template_version: master 33 | 34 | - name: marketing-offer-generator-waw 35 | port: 8056 36 | template: https://github.com/4finance/boot-microservice.git 37 | template_version: master 38 | 39 | - name: reporting-service-waw 40 | port: 8057 41 | template: https://github.com/4finance/boot-microservice.git 42 | template_version: boot-microservice-gui-without-node 43 | 44 | - name: client-service-waw 45 | port: 8058 46 | template: https://github.com/4finance/boot-microservice.git 47 | template_version: boot-microservice-gui-without-node 48 | 49 | - name: ui-lodz 50 | port: 9052 51 | template: https://github.com/4finance/boot-microservice.git 52 | template_version: boot-microservice-gui-without-node 53 | 54 | - name: fraud-detection-service-lodz 55 | port: 9053 56 | template: https://github.com/4finance/boot-microservice.git 57 | template_version: master 58 | 59 | - name: loan-application-service-lodz 60 | port: 9054 61 | template: https://github.com/4finance/boot-microservice.git 62 | template_version: master 63 | 64 | - name: loan-application-decision-maker-lodz 65 | port: 9055 66 | template: https://github.com/4finance/boot-microservice.git 67 | template_version: master 68 | 69 | - name: marketing-offer-generator-lodz 70 | port: 9056 71 | template: https://github.com/4finance/boot-microservice.git 72 | template_version: master 73 | 74 | - name: reporting-service-lodz 75 | port: 9057 76 | template: https://github.com/4finance/boot-microservice.git 77 | template_version: boot-microservice-gui-without-node 78 | 79 | - name: client-service-lodz 80 | port: 9058 81 | template: https://github.com/4finance/boot-microservice.git 82 | template_version: boot-microservice-gui-without-node 83 | -------------------------------------------------------------------------------- /hackathons/2015-08-28-codepot-warszawa.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | domain: codepot 4 | github_organization: Codepot-Microservices-2015-08 5 | docs_title: "Codepot Microservices - Warszawa 2015-08-26" 6 | 7 | docs: 8 | - name: "{{ github_organization }}.github.io" 9 | template: ssh://git@github.com/microservice-hackathon/docs-template.git 10 | template_version: master 11 | 12 | properties: 13 | - name: "properties" 14 | template: ssh://git@github.com/2015-06-devoxx-microservices/properties.git 15 | 16 | projects: 17 | 18 | - name: aggregatr-blue 19 | port: 9090 20 | template: ssh://git@github.com/2015-06-devoxx-microservices/aggregatr.io.git 21 | 22 | - name: butelkatr-blue 23 | port: 9091 24 | template: ssh://git@github.com/2015-06-devoxx-microservices/butelkatr.io.git 25 | 26 | - name: dojrzewatr-blue 27 | port: 9092 28 | template: ssh://git@github.com/2015-06-devoxx-microservices/dojrzewatr.io.git 29 | 30 | - name: prezentatr-blue 31 | port: 9093 32 | template: ssh://git@github.com/2015-06-devoxx-microservices/prezentatr.io.git 33 | 34 | - name: aggregatr-red 35 | port: 9190 36 | template: ssh://git@github.com/2015-06-devoxx-microservices/aggregatr.io.git 37 | 38 | - name: butelkatr-red 39 | port: 9191 40 | template: ssh://git@github.com/2015-06-devoxx-microservices/butelkatr.io.git 41 | 42 | - name: dojrzewatr-red 43 | port: 9192 44 | template: ssh://git@github.com/2015-06-devoxx-microservices/dojrzewatr.io.git 45 | 46 | - name: prezentatr-red 47 | port: 9193 48 | template: ssh://git@github.com/2015-06-devoxx-microservices/prezentatr.io.git 49 | -------------------------------------------------------------------------------- /hackathons/2015-09-08-wjug-warszawa.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | domain: wjug 4 | github_organization: 2015-09-wjug-microservices 5 | docs_title: "WJUG Microservices - Warszawa 2015-09-08" 6 | 7 | docs: 8 | - name: "{{ github_organization }}.github.io" 9 | template: ssh://git@github.com/microservice-hackathon/docs-template.git 10 | template_version: master 11 | 12 | properties: 13 | - name: "properties" 14 | template: ssh://git@github.com/2015-06-devoxx-microservices/properties.git 15 | 16 | projects: 17 | 18 | - name: aggregatr.io 19 | port: 9090 20 | template: ssh://git@github.com/2015-06-devoxx-microservices/aggregatr.io.git 21 | 22 | - name: butelkatr.io 23 | port: 9091 24 | template: ssh://git@github.com/2015-06-devoxx-microservices/butelkatr.io.git 25 | 26 | - name: dojrzewatr.io 27 | port: 9092 28 | template: ssh://git@github.com/2015-06-devoxx-microservices/dojrzewatr.io.git 29 | 30 | - name: prezentatr.io 31 | port: 9093 32 | template: ssh://git@github.com/2015-06-devoxx-microservices/prezentatr.io.git 33 | -------------------------------------------------------------------------------- /hackathons/default.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | # default domain 4 | domain: uservices.local 5 | 6 | # logstash configuration 7 | logstash_forwarder_cert: files/certs/logstash-forwarder.pem 8 | logstash_forwarder_key: files/certs/logstash-forwarder.key 9 | logstash_lumberjack_host: kibana.{{ domain }} 10 | logstash_lumberjack_port: 5043 11 | 12 | # graphite configuration 13 | graphite_host: graphite.{{ domain }} 14 | grafana_host: grafana.{{ domain }} 15 | 16 | # ES configuration 17 | elasticsearch_host: elasticsearch.{{ domain }} 18 | 19 | # rundeck configuration 20 | rundeck_host: rundeck.{{ domain }} 21 | 22 | # nexus configuration 23 | nexus_url: http://nexus.{{ domain }}:8081/nexus 24 | 25 | # seyren configuration 26 | seyren_graphite_url: "http://{{ graphite_host }}" 27 | seyren_port: 8080 28 | seyren_url: "http://{{ graphite_host }}:{{ seyren_port }}" 29 | 30 | # kibana 31 | kibana_host: "kibana.{{ domain }}" 32 | 33 | # tools location 34 | tools: 35 | - name: Rundeck 36 | url: "http://rundeck.{{ domain }}:4440" 37 | 38 | - name: Nexus 39 | url: "http://nexus.{{ domain }}:8081/nexus/" 40 | 41 | - name: Graphite 42 | url: "http://graphite.{{ domain }}/" 43 | 44 | - name: Grafana 45 | url: "http://grafana.{{ domain }}/" 46 | 47 | - name: Kibana 48 | url: "http://kibana.{{ domain }}/" 49 | 50 | - name: Exhibitor 51 | url: "http://apps.{{ domain }}:8080/exhibitor/v1/ui/index.html" 52 | 53 | - name: Jenkins 54 | url: "http://jenkins.{{ domain }}:8080/" 55 | 56 | # jenkins 57 | jenkins_seed_job_git_url: https://github.com/uservices-hackathon/jenkins-pipeline-dsl-example.git 58 | jenkins_seed_job_git_branch: sample_pipeline 59 | 60 | # rundeck 61 | rundeck_ssh_private_key: files/certs/rundeck_id_rsa 62 | rundeck_ssh_public_key: files/certs/rundeck_id_rsa.pub 63 | rundeck_projects: 64 | - name: "deploy" 65 | ssh_keypath: "{{ rundeck_basedir }}/.ssh/id_rsa" 66 | definition: 67 | - name: Deploy 68 | loglevel: INFO 69 | multipleExecutions: true 70 | sequence: 71 | keepgoing: false 72 | strategy: step-first 73 | commands: 74 | - scripturl: https://raw.githubusercontent.com/microservice-hackathon/infrastructure/master/scripts/deploy-microservice.sh 75 | nodefilters: 76 | dispatch: 77 | excludePrecedence: true 78 | keepgoing: false 79 | rankOrder: ascending 80 | threadcount: 1 81 | filter: 'apps name: apps' 82 | nodesSelectedByDefault: true 83 | options: 84 | groupId: 85 | required: true 86 | artifactId: 87 | required: true 88 | version: 89 | required: true 90 | nexusUrl: 91 | required: true 92 | resources: 93 | apps: 94 | tags: '' 95 | osFamily: unix 96 | username: root 97 | osArch: amd64 98 | description: App server 99 | nodename: "apps.{{ domain }}" 100 | hostname: "apps.{{ domain }}" 101 | osName: Linux 102 | 103 | # deploy role configuration 104 | deploy_rundeck_public_key: "{{ rundeck_ssh_public_key }}" 105 | -------------------------------------------------------------------------------- /hackathons/docs/2015-02-23-4financeit-prague.md: -------------------------------------------------------------------------------- 1 | Microservice Hackathon 2 | ====================== 3 | 4 | Welcome to the Microservice Hackathon! 5 | 6 | Here you find all information required for you to work during the Hackathon. 7 | 8 | # Link to the presentation 9 | 10 | [Presentation about microservices](https://docs.google.com/presentation/d/1alWCqeNK2KT-bjidlGZ_tvoN5hYQT0VBhbMcrOzkGyU/edit?usp=sharing) 11 | 12 | # Ok what should I do now? 13 | 14 | Well, let your team pick a service and start coding. Once you commit and push, 15 | Jenkins will build that for you and upload your JAR to nexus. Next Rundeck will 16 | deploy your application to the apps server. 17 | 18 | Each of the microservices will have a predefined port at which it will listen 19 | to requests so you don't have to worry about that. 20 | 21 | # I have a UI based microservice - where is my readme?! 22 | 23 | Check this out [boot-microservice-gui-readme](https://github.com/4finance/boot-microservice-gui) 24 | 25 | # I have a backend based microservice - where is my readme?! 26 | 27 | Check this out [boot-microservice-readme](https://github.com/4finance/boot-microservice) 28 | 29 | # I have to implement a microservice with a DB - what should I do? 30 | 31 | For a relational DB use H2 in memory. 32 | 33 | For a NoSQL one use [Fongo](https://github.com/fakemongo/fongo) in compile scope. 34 | 35 | # How to run my microservice locally 36 | 37 | We give you Spring profiles! Just add a system property: 38 | 39 | ```bash 40 | -Dspring.profiles.active=dev 41 | ``` 42 | 43 | # Architecture 44 | 45 | ## Architecture draft 46 | 47 | [Click to see the draft](https://docs.google.com/document/d/1yRV5DNJAhBH73bJo-s5L8wwoeJG4Ke6H45dg8_rRT84/edit?usp=sharing) 48 | 49 | ## Architecture plan 50 | 51 | [Click to see the plan](https://drive.google.com/file/d/0B4mHLrLla3S8VHd3QXZrZ25yb1U/view?usp=sharing) 52 | 53 | ## Formats of incoming messages (only suggestion! decide yourself) 54 | 55 | ### FraudDetectionService 56 | 57 | PUT /api/loanApplication/{loanApplicationId} 58 | 59 | ```json 60 | { 61 | "firstName" : "text", 62 | "lastName" : "text", 63 | "job" : "text", 64 | "amount" : number, 65 | "age" : number 66 | } 67 | ``` 68 | 69 | ###LoanApplicationDecisionMaker 70 | 71 | PUT /api/loanApplication/{loanApplicationId} 72 | 73 | ```json 74 | { 75 | "firstName" : "text", 76 | "lastName" : "text", 77 | "job" : "text", 78 | "amount" : number, 79 | "fraudStatus" : "text" 80 | } 81 | ``` 82 | 83 | GET /api/loanApplication/{loanApplicationId} 84 | ```json 85 | { 86 | "applicationId" : "text", 87 | "result" : boolean 88 | } 89 | ``` 90 | 91 | ###ClientService 92 | 93 | POST /api/client 94 | 95 | ```json 96 | { 97 | "firstName" : "text", 98 | "lastName" : "text", 99 | "age": number, 100 | "loanId" : "text" (This is actually the loan application identifier.) 101 | } 102 | ``` 103 | ###LoanApplicationService 104 | 105 | POST /api/loanApplication 106 | 107 | ```json 108 | { 109 | "amount": number, 110 | "loanId" : "text" (This is actually the loan application identifier.) 111 | } 112 | ``` 113 | 114 | ###ReportingService 115 | 116 | POST /api/client 117 | 118 | ```json 119 | { 120 | "firstName" : "text", 121 | "lastName" : "text", 122 | "age": number, 123 | "loanId" : "text" (This is actually the loan application identifier.) 124 | } 125 | ``` 126 | 127 | POST /api/reporting 128 | 129 | ```json 130 | { 131 | "loanId" : "text", 132 | "job" : "text", 133 | "amount" : number, 134 | "fraudStatus" : "text", 135 | "decision" : "text" 136 | } 137 | ``` 138 | 139 | ###MarketingOfferGenerator 140 | 141 | PUT /api/marketing/{loanApplicationId} 142 | 143 | ```json 144 | { 145 | "person" : { 146 | "firstName" : "text", 147 | "lastName" : "text" 148 | }, 149 | "decision" : "text" 150 | } 151 | ``` 152 | 153 | GET /api/marketing/{firstName}_{lastName} 154 | 155 | ```json 156 | { 157 | "marketingOffer" : "text" 158 | } 159 | ``` 160 | -------------------------------------------------------------------------------- /hackathons/docs/2015-03-21-jug-lodz.md: -------------------------------------------------------------------------------- 1 | Microservice Hackathon 2 | ====================== 3 | 4 | Welcome to the Microservice Hackathon! 5 | 6 | Here you find all information required for you to work during the Hackathon. 7 | 8 | # Sponsors 9 | 10 | ![Lodz JUG](/images/lodzjug.png "Lodz JUG") 11 | ![Amazon Web Services](/images/aws.png "AWS") 12 | ![GFT](/images/gftlogo.jpg "GFT") 13 | ![4financeIT](/images/4finance-logo.png "4financeIT") 14 | 15 | # Link to the presentation 16 | 17 | [Presentation about microservices](https://docs.google.com/presentation/d/17cCAQ1wBE6qkBuIgFQWOME3T9ARMKRa88JC32kIwFMo/) 18 | 19 | # Ok what should I do now? 20 | 21 | ## Clone the GIT properties repository to your computer 22 | 23 | Run this command (if you have sent your SSH key to Github) 24 | 25 | ``` 26 | git clone git@github.com:microhackathon-2015-03-juglodz/properties.git 27 | 28 | ``` 29 | 30 | or if you can't conect to Github via ssh 31 | 32 | ``` 33 | git clone https://github.com/microhackathon-2015-03-juglodz/properties.git 34 | 35 | ``` 36 | 37 | ## Set environment variable for GIT properties 38 | 39 | For Linux 40 | 41 | ```bash 42 | ### Configuration which should be placed on server where app is deployed 43 | # Environment where our app is deployed, configuration will be taken from corresponding dir 44 | export APP_ENV="prod" 45 | # Git repository with configuration. Absolute path should be used. 46 | export CONFIG_FOLDER="/path/to/your/checked/out/git/repository" 47 | # For secretProd env, ENCRYPT_KEY is required. 48 | # Use encrypt.key if you pass it as -D option when running java 49 | export ENCRYPT_KEY="secretEncryptKey" 50 | 51 | ``` 52 | 53 | For Windows 54 | 55 | either do it via some UI or run this command 56 | 57 | ```batch 58 | rem ### Configuration which should be placed on server where app is deployed 59 | rem Environment where our app is deployed, configuration will be taken from corresponding dir 60 | @set APP_ENV="prod" 61 | rem Git repository with configuration. Absolute path should be used. 62 | @set CONFIG_FOLDER="C:/path/to/your/checked/out/git/repository" 63 | rem For secretProd env, ENCRYPT_KEY is required. 64 | rem Use encrypt.key if you pass it as -D option when running java 65 | @set ENCRYPT_KEY="secretEncryptKey" 66 | 67 | ``` 68 | 69 | For easy microservice execution just modify the proper `/scripts/run.sh` or `/scripts/run.bat` to include the path to your git repo 70 | 71 | ## Clone your microservice and start coding! 72 | 73 | Well, let your team pick a service and start coding. Once you commit and push, 74 | Jenkins will build that for you and upload your JAR to nexus. Next Rundeck will 75 | deploy your application to the apps server. 76 | 77 | Each of the microservices will have a predefined port at which it will listen 78 | to requests so you don't have to worry about that. 79 | 80 | # I have a UI based microservice - where is my readme?! 81 | 82 | Check this out [boot-microservice-gui-readme](https://github.com/4finance/boot-microservice#boot-microservice-gui--). Just scroll to the very bottom ;) 83 | 84 | # I have a backend based microservice - where is my readme?! 85 | 86 | Check this out [boot-microservice-readme](https://github.com/4finance/boot-microservice) 87 | 88 | # I have to implement a microservice with a DB - what should I do? 89 | 90 | For a relational DB use H2 in memory. 91 | 92 | For a NoSQL one use [Fongo](https://github.com/fakemongo/fongo) in compile scope. 93 | 94 | # How to run my microservice locally 95 | 96 | It's all there in the readme - [boot-microservice-readme](https://github.com/4finance/boot-microservice) 97 | 98 | # Architecture 99 | 100 | ## Architecture draft 101 | 102 | [Click to see the draft](https://docs.google.com/document/d/1yRV5DNJAhBH73bJo-s5L8wwoeJG4Ke6H45dg8_rRT84/edit?usp=sharing) 103 | 104 | ## Architecture plan 105 | 106 | [Click to see the plan](https://drive.google.com/file/d/0B4mHLrLla3S8VHd3QXZrZ25yb1U/view?usp=sharing) 107 | 108 | ## Formats of incoming messages (only suggestion! decide yourself) 109 | 110 | ### FraudDetectionService 111 | 112 | PUT /api/loanApplication/{loanApplicationId} 113 | 114 | ```json 115 | { 116 | "firstName" : "text", 117 | "lastName" : "text", 118 | "job" : "text", 119 | "amount" : number, 120 | "age" : number 121 | } 122 | ``` 123 | 124 | ###LoanApplicationDecisionMaker 125 | 126 | PUT /api/loanApplication/{loanApplicationId} 127 | 128 | ```json 129 | { 130 | "firstName" : "text", 131 | "lastName" : "text", 132 | "job" : "text", 133 | "amount" : number, 134 | "fraudStatus" : "text" 135 | } 136 | ``` 137 | 138 | GET /api/loanApplication/{loanApplicationId} 139 | ```json 140 | { 141 | "applicationId" : "text", 142 | "result" : boolean 143 | } 144 | ``` 145 | 146 | ###ClientService 147 | 148 | POST /api/client 149 | 150 | ```json 151 | { 152 | "firstName" : "text", 153 | "lastName" : "text", 154 | "age": number, 155 | "loanId" : "text" (This is actually the loan application identifier.) 156 | } 157 | ``` 158 | ###LoanApplicationService 159 | 160 | POST /api/loanApplication 161 | 162 | ```json 163 | { 164 | "amount": number, 165 | "loanId" : "text" (This is actually the loan application identifier.) 166 | } 167 | ``` 168 | 169 | ###ReportingService 170 | 171 | POST /api/client 172 | 173 | ```json 174 | { 175 | "firstName" : "text", 176 | "lastName" : "text", 177 | "age": number, 178 | "loanId" : "text" (This is actually the loan application identifier.) 179 | } 180 | ``` 181 | 182 | POST /api/reporting 183 | 184 | ```json 185 | { 186 | "loanId" : "text", 187 | "job" : "text", 188 | "amount" : number, 189 | "fraudStatus" : "text", 190 | "decision" : "text" 191 | } 192 | ``` 193 | 194 | ###MarketingOfferGenerator 195 | 196 | PUT /api/marketing/{loanApplicationId} 197 | 198 | ```json 199 | { 200 | "person" : { 201 | "firstName" : "text", 202 | "lastName" : "text" 203 | }, 204 | "decision" : "text" 205 | } 206 | ``` 207 | 208 | GET /api/marketing/{firstName}_{lastName} 209 | 210 | ```json 211 | { 212 | "marketingOffer" : "text" 213 | } 214 | ``` 215 | -------------------------------------------------------------------------------- /hackathons/docs/2015-08-28-codepot-warszawa.md: -------------------------------------------------------------------------------- 1 | Microservice Hackathon 2 | ====================== 3 | 4 | Welcome to the Microservice Hackathon! 5 | 6 | Here you find all information required for you to work during the Hackathon. 7 | 8 | # Link to the presentation 9 | 10 | [Presentation about microservices](https://docs.google.com/presentation/d/17cCAQ1wBE6qkBuIgFQWOME3T9ARMKRa88JC32kIwFMo/) 11 | 12 | # Ok what should I do now? 13 | 14 | ## Clone the GIT properties repository to your computer 15 | 16 | Run this command (if you have sent your SSH key to Github) 17 | 18 | ``` 19 | git clone git@github.com:microhackathon-2015-03-juglodz/properties.git 20 | 21 | ``` 22 | 23 | or if you can't conect to Github via ssh 24 | 25 | ``` 26 | git clone https://github.com/microhackathon-2015-03-juglodz/properties.git 27 | 28 | ``` 29 | 30 | ## Set environment variable for GIT properties 31 | 32 | For Linux 33 | 34 | ```bash 35 | ### Configuration which should be placed on server where app is deployed 36 | # Environment where our app is deployed, configuration will be taken from corresponding dir 37 | export APP_ENV="prod" 38 | # Git repository with configuration. Absolute path should be used. 39 | export CONFIG_FOLDER="/path/to/your/checked/out/git/repository" 40 | # For secretProd env, ENCRYPT_KEY is required. 41 | # Use encrypt.key if you pass it as -D option when running java 42 | export ENCRYPT_KEY="secretEncryptKey" 43 | 44 | ``` 45 | 46 | For Windows 47 | 48 | either do it via some UI or run this command 49 | 50 | ```batch 51 | rem ### Configuration which should be placed on server where app is deployed 52 | rem Environment where our app is deployed, configuration will be taken from corresponding dir 53 | @set APP_ENV="prod" 54 | rem Git repository with configuration. Absolute path should be used. 55 | @set CONFIG_FOLDER="C:/path/to/your/checked/out/git/repository" 56 | rem For secretProd env, ENCRYPT_KEY is required. 57 | rem Use encrypt.key if you pass it as -D option when running java 58 | @set ENCRYPT_KEY="secretEncryptKey" 59 | 60 | ``` 61 | 62 | For easy microservice execution just modify the proper `/scripts/run.sh` or `/scripts/run.bat` to include the path to your git repo 63 | 64 | ## Clone your microservice and start coding! 65 | 66 | Well, let your team pick a service and start coding. Once you commit and push, 67 | Jenkins will build that for you and upload your JAR to nexus. Next Rundeck will 68 | deploy your application to the apps server. 69 | 70 | Each of the microservices will have a predefined port at which it will listen 71 | to requests so you don't have to worry about that. 72 | 73 | # I have a UI based microservice - where is my readme?! 74 | 75 | Check this out [boot-microservice-gui-readme](https://github.com/4finance/boot-microservice#boot-microservice-gui--). Just scroll to the very bottom ;) 76 | 77 | # I have a backend based microservice - where is my readme?! 78 | 79 | Check this out [boot-microservice-readme](https://github.com/4finance/boot-microservice) 80 | 81 | # I have to implement a microservice with a DB - what should I do? 82 | 83 | For a relational DB use H2 in memory. 84 | 85 | For a NoSQL one use [Fongo](https://github.com/fakemongo/fongo) in compile scope. 86 | 87 | # How to run my microservice locally 88 | 89 | It's all there in the readme - [boot-microservice-readme](https://github.com/4finance/boot-microservice) 90 | 91 | # Architecture 92 | 93 | ## Architecture draft 94 | 95 | [Click to see the draft](https://docs.google.com/document/d/1yRV5DNJAhBH73bJo-s5L8wwoeJG4Ke6H45dg8_rRT84/edit?usp=sharing) 96 | 97 | ## Architecture plan 98 | 99 | [Click to see the plan](https://drive.google.com/file/d/0B4mHLrLla3S8VHd3QXZrZ25yb1U/view?usp=sharing) 100 | 101 | ## Formats of incoming messages (only suggestion! decide yourself) 102 | 103 | ### FraudDetectionService 104 | 105 | PUT /api/loanApplication/{loanApplicationId} 106 | 107 | ```json 108 | { 109 | "firstName" : "text", 110 | "lastName" : "text", 111 | "job" : "text", 112 | "amount" : number, 113 | "age" : number 114 | } 115 | ``` 116 | 117 | ###LoanApplicationDecisionMaker 118 | 119 | PUT /api/loanApplication/{loanApplicationId} 120 | 121 | ```json 122 | { 123 | "firstName" : "text", 124 | "lastName" : "text", 125 | "job" : "text", 126 | "amount" : number, 127 | "fraudStatus" : "text" 128 | } 129 | ``` 130 | 131 | GET /api/loanApplication/{loanApplicationId} 132 | ```json 133 | { 134 | "applicationId" : "text", 135 | "result" : boolean 136 | } 137 | ``` 138 | 139 | ###ClientService 140 | 141 | POST /api/client 142 | 143 | ```json 144 | { 145 | "firstName" : "text", 146 | "lastName" : "text", 147 | "age": number, 148 | "loanId" : "text" (This is actually the loan application identifier.) 149 | } 150 | ``` 151 | ###LoanApplicationService 152 | 153 | POST /api/loanApplication 154 | 155 | ```json 156 | { 157 | "amount": number, 158 | "loanId" : "text" (This is actually the loan application identifier.) 159 | } 160 | ``` 161 | 162 | ###ReportingService 163 | 164 | POST /api/client 165 | 166 | ```json 167 | { 168 | "firstName" : "text", 169 | "lastName" : "text", 170 | "age": number, 171 | "loanId" : "text" (This is actually the loan application identifier.) 172 | } 173 | ``` 174 | 175 | POST /api/reporting 176 | 177 | ```json 178 | { 179 | "loanId" : "text", 180 | "job" : "text", 181 | "amount" : number, 182 | "fraudStatus" : "text", 183 | "decision" : "text" 184 | } 185 | ``` 186 | 187 | ###MarketingOfferGenerator 188 | 189 | PUT /api/marketing/{loanApplicationId} 190 | 191 | ```json 192 | { 193 | "person" : { 194 | "firstName" : "text", 195 | "lastName" : "text" 196 | }, 197 | "decision" : "text" 198 | } 199 | ``` 200 | 201 | GET /api/marketing/{firstName}_{lastName} 202 | 203 | ```json 204 | { 205 | "marketingOffer" : "text" 206 | } 207 | ``` 208 | -------------------------------------------------------------------------------- /hackathons/docs/2015-09-08-wjug-warszawa.md: -------------------------------------------------------------------------------- 1 | Codepot 2015 Workshop 2 | ===================== 3 | 4 | Welcome to the Codepot 2015 Workshop! 5 | 6 | Here you find all information required for you to work during the Codepot 2015 Workshop. 7 | 8 | # Table of contents 9 | 10 | - [Documentation](#documentation) 11 | - [Ok what should I do now?](#ok-what-should-I-do-now) 12 | - [What is the feature that I'm supposed to do?](#what-feature) 13 | - [When is my feature done?](#when-is-my-feature-done) 14 | - [Where's the URL of my service that I should clone?](#ports) 15 | - [How to run my microservice locally](#how-to-run-my-microservice-locally) 16 | - [What's my service's port?](#ports) 17 | - [Where are all the tools?](#tools) 18 | - [Useful snippets / info](#useful-snippets-info) 19 | - [/etc/hosts entries](#hosts) 20 | - [Spring Rest Controller example](#spring-rest-controller) 21 | - [Service Rest Client example](#service-rest-client) 22 | - [Metrics setting example](#metrics) 23 | - [Seyren setup example](#seyren) 24 | - [Working example of the whole setup](#working) 25 | 26 | --- 27 | 28 | # Documentation 29 | 30 | ## Good to do before the workshop 31 | 32 | - Clone and build boot-microservice so that all the libraries get downloaded. 33 | - [Link to the boot-microservice repository](https://github.com/4finance/boot-microservice) which will be the base for the services that we will build 34 | - Execute command `git clone git@github.com:4finance/boot-microservice.git && cd boot-microservice && ./gradlew clean build` to clone and built the application 35 | - [Read about Microservices](http://martinfowler.com/articles/microservices.html) 36 | - [Watch a video about Microservices](https://www.youtube.com/watch?v=wgdBVIX9ifA) 37 | - [Read about 12 Factor App](http://12factor.net/) 38 | - [Read about Micro-Infra-Spring](https://github.com/4finance/micro-infra-spring/wiki) 39 | - [Watch a video about Micro-Infra Spring](https://www.youtube.com/watch?v=D6V49K_Yb8g) 40 | - [Read about Consumer Driven Contracts] (http://martinfowler.com/articles/consumerDrivenContracts.html) 41 | - [Watch a video about Consumer Driven Contracts](https://vimeo.com/130779882) 42 | 43 | ### If you don't know anything about Spring / Guava / Concurrency 44 | 45 | - [Read a getting started to Spring Boot](https://spring.io/guides/gs/spring-boot/) 46 | - [Read about ListenableFuture](https://code.google.com/p/guava-libraries/wiki/ListenableFutureExplained) 47 | - [Definitive guide to CompletableFuture](http://www.nurkiewicz.com/2013/05/java-8-definitive-guide-to.html) 48 | 49 | ## Presentations and introductions 50 | 51 | - [Codepot presentation](https://docs.google.com/presentation/d/1ZSMaZJrvurvH3-EKuI2DXifKenPVp2xq80uzJvr7yzs/edit?usp=sharing) 52 | - [Micro-Infra spring fast introduction - online](https://docs.google.com/presentation/d/1xbdOWYvuGKnp-_1wGz-bZTobEbCePRr062YUnx4jTQg/edit?usp=sharing) 53 | - [Micro-Infra spring fast introduction - pdf](resources/Microservices_Codepot.pdf) 54 | 55 | ## Additional links 56 | 57 | - [Ansible scripts used for provisioning of the Workshop setup](https://github.com/microservice-hackathon/infrastructure) 58 | - [Jenkins-DSL code to setup Jenkins jobs for the Workshop](https://github.com/microservice-hackathon/jenkins/tree/2015-08-codepot-offline) 59 | - [Micro-Infra-Spring codebase](https://github.com/4finance/micro-infra-spring) 60 | 61 | --- 62 | 63 | # Ok what should I do now? 64 | 65 | ## Set up /etc/hosts 66 | 67 | Go to your `/etc/hosts` and append values like presented in the code snippet [here](#hosts) 68 | 69 | ## Clone the GIT properties repository to your computer 70 | 71 | Clone repositories from [https://github.com/Codepot-Microservices-2015-08](https://github.com/Codepot-Microservices-2015-08) 72 | 73 | Run this command (if you have sent your SSH key to Github) to clone the properties repository 74 | 75 | ``` 76 | git clone git@github.com:Codepot-Microservices-2015-08/properties.git 77 | ``` 78 | 79 | And the appropriate service i.e. `butelkatr` for `red` team: 80 | 81 | ``` 82 | git clone git@github.com:Codepot-Microservices-2015-08/butelkatr-red.git 83 | ``` 84 | 85 | ## Start coding! 86 | 87 | Well, let your team pick a service and start coding. Once you commit and push, 88 | Jenkins will build that for you and upload your JAR to nexus. Next Rundeck will 89 | deploy your application to the apps server. 90 | 91 | Each of the microservices will have a predefined port at which it will listen 92 | to requests so you don't have to worry about that. 93 | 94 | The ports are presented below in the table. 95 | 96 | ### Reminder! 97 | 98 | Try to be as reactive and non-blocking as possible! 99 | 100 | --- 101 | 102 | # What is the feature that I'm supposed to do? 103 | 104 | ## Main feature - Brewery 105 | 106 | - client clicks on prezentatr.io UI to order ingredients. Prezentatr.io calls aggregatr.io to start fetching ingredients 107 | - aggregatr.io calls external services to fetch ingredients and once a threshold has been met sends them to dojrzewatr.io 108 | - dojrzewatr.io waits for some time (matures the beer) and sends the WORT to butelkatr.io 109 | - butelkatr.io basing on the amount of wort produces bottles 110 | - each service has to report back to prezentatr.io about statuses 111 | 112 | All the implementation details are to be decided between you. Note that the Accurest contracts will already give you 113 | hints on how the feature should be done. 114 | 115 | --- 116 | 117 | # When is my feature done? 118 | 119 | The definition of done is as follows: 120 | 121 | - the task has been successfully implemented 122 | - you have tests that back that up 123 | - you have created a metric to verify your feature 124 | - your feature has production alerting in Seyren 125 | - each team has its own Slack room with alerts popping up 126 | - there are dashboards on [kibana](http://kibana.codepot/#/dashboard/file/default.json) (logs) and [grafana](http://grafana.codepot/#/dashboard/file/default.json) (metrics) set up 127 | 128 | --- 129 | 130 | # How to run my microservice locally 131 | 132 | It's all there in the readme - [boot-microservice-readme](https://github.com/4finance/boot-microservice) 133 | 134 | --- 135 | 136 | # Useful snippets / info 137 | 138 | ## Spring Rest Controller example 139 | 140 | Example of a `Controller` with an endpoint at URL `/video` that accepts the `content-type` header equal to `application/vnd.some.service.v1+json` 141 | and produces a `JSON` as output. You have to call it via `POST` HTTP method 142 | 143 | ```java 144 | @RestController 145 | @RequestMapping(value = "/video", consumes = "application/vnd.some.service.v1+json", produces = MediaType.APPLICATION_JSON_VALUE) 146 | public class SomeController { 147 | 148 | private final VideoService videoService; 149 | 150 | @Autowired 151 | public SomeController(VideoService videoService) { 152 | this.videoService = videoService; 153 | } 154 | 155 | @RequestMapping(method = RequestMethod.POST) 156 | public Videos doSomeFancyStuff(@RequestBody SomeRequestBody someRequestBody) { 157 | return videoService.doSomethingAwesome(someRequestBody); 158 | } 159 | } 160 | ``` 161 | 162 | ## Service Rest Client example 163 | 164 | Example of a component registered via `@Component` (you should use `@Configuration` to register beans) that uses 165 | `ServiceRestClient` to call other components. 166 | 167 | ```java 168 | import com.netflix.hystrix.HystrixCommand; 169 | import com.nurkiewicz.asyncretry.RetryExecutor; 170 | import com.ofg.infrastructure.web.resttemplate.fluent.ServiceRestClient; 171 | import com.netflix.hystrix.HystrixCommand; 172 | 173 | import static com.netflix.hystrix.HystrixCommandGroupKey.Factory.asKey; 174 | 175 | @Component 176 | public class VideoService { 177 | 178 | private final ServiceRestClient serviceRestClient; 179 | private final RetryExecutor retryExecutor; 180 | 181 | @Autowired 182 | public VideoService(ServiceRestClient serviceRestClient, RetryExecutor retryExecutor) { 183 | this.serviceRestClient = serviceRestClient; 184 | this.retryExecutor = retryExecutor; 185 | } 186 | 187 | public ListenableFuture doSomethingAwesome(Ingredients ingredients) { 188 | return serviceRestClient.forService("someAliasFromMicroserviceDescriptor") 189 | .retryUsing(retryExecutor) 190 | .post() 191 | .withCircuitBreaker(HystrixCommand.Setter.withGroupKey(asKey("hystrix_group"))) 192 | .onUrl("/someUrlToWhichYouWantToSendARequest") 193 | .body(ingredients) 194 | .withHeaders().contentType("application/vnd.some.other.service.v1+json") 195 | .andExecuteFor() 196 | .anObject() 197 | .ofTypeAsync(Videos.class) 198 | } 199 | } 200 | ``` 201 | 202 | 203 | ## Metrics setup example 204 | 205 | ```java 206 | @Component 207 | class IngredientsAggregator { 208 | 209 | private final SomeService someService; 210 | private final Meter someMeter; 211 | 212 | @Autowired 213 | IngredientsAggregator(MetricRegistry metricRegistry, SomeService someService) { 214 | this.someService = someService; 215 | this.someMeter = metricRegistry.meter("name.of.a.meter.metric"); 216 | setupMeters(metricRegistry); 217 | } 218 | 219 | private void setupMeters(MetricRegistry metricRegistry) { 220 | metricRegistry.register("name.of.the.gauge.metric", (Gauge) () -> someService.getValueForGauge()); 221 | } 222 | 223 | public void doSomethingMeaningful(long sample) { 224 | // do something and mark the metric 225 | someMeter.mark(sample); 226 | // do something else 227 | } 228 | 229 | } 230 | 231 | ``` 232 | 233 | ## How to take current CorrelationID 234 | 235 | Use the following snippet 236 | 237 | ``` 238 | import com.ofg.infrastructure.correlationid.CorrelationIdHolder; 239 | 240 | 241 | CorrelationIdHolder.get(); 242 | 243 | ``` 244 | 245 | ## How to configure alerting in Seyren 246 | 247 | In order to add alerting in Seyren you have to first: 248 | 249 | - Add hosts entries as presented in this doc 250 | - Go to `http://seyren.codepot` 251 | 252 | Now do the following actions: 253 | 254 | ### Go to checks 255 | 256 | Click the _Checks_ button to the top: 257 | 258 | ![alt text](images/seyren/seyren_checks.png "Seyren Checks") 259 | 260 | ### Create a new check 261 | 262 | In the checks site you will have a list of already created checks. 263 | 264 | Click the _Create check_ button to the top right: 265 | 266 | ![alt text](images/seyren/seyren_create_check.png "Create Seyren Check") 267 | 268 | ### Fill out the dialog 269 | 270 | ![alt text](images/seyren/seyren_create_check_dialog.png "Create Seyren Check Dialog") 271 | 272 | Here you have a description of the fields. 273 | 274 | - Name 275 | - Name of the alert in format: [REALM][APP] Alert name 276 | - Example: `[RED][BUTELKATR] Number of beer bottles` 277 | - Description 278 | - Description of the alert 279 | - Example: `Number of beer bottles` 280 | - Target 281 | - Function from Graphite basing on a Graphite metric. Example shows a Graphite function keepLastValue applied to a Graphite metric. Note that you might get NULL values from Graphite so keepLastValue is a function that in that case will help you pick the last value that was present in Graphite. 282 | - Example: `keepLastValue(.*.red.butelkatr.bottles.meter.m15_rate)` 283 | - Read more here about Graphite functions: [Graphite functions](https://graphite.readthedocs.org/en/0.9.10/functions.html) 284 | - Warn level 285 | - What is the threshold that when the metric goes BELOW will set the level to WARN 286 | - Example: `100` 287 | - Error level 288 | - What is the threshold that when the metric goes BELOW will set the level to ERROR 289 | - Example: `10` 290 | - Enabled 291 | - Enables the metric 292 | - Can be (on) or (off) 293 | - Allow no data 294 | - Assumes that if there are null values then it's not a problem 295 | - Can be (on) or (off) 296 | 297 | ### Add subscription 298 | 299 | Once you've added a metric most likely you want to get notified if some threshold has been reached. To do that you have to add a subscription: 300 | 301 | ![alt text](images/seyren/seyren_add_subscription.png "Create Subscription for an alert") 302 | 303 | ### Fill out the subscription dialog 304 | 305 | Pick `Slack` as _Type_ and type in the _channel name with a hash at the beginning`. e.g. `#channel` 306 | 307 | ![alt text](images/seyren/seyren_create_subscription.png "Fill out the subscription dialog") 308 | 309 | ## How to run in debug mode with stubs from nexus 310 | 311 | application.yaml 312 | 313 | ```yaml 314 | stubrunner: 315 | #skip-local-repo: false 316 | #work-offline: true 317 | use-microservice-definitions: true 318 | stubs: 319 | repository.root: "http://52.16.215.68:8081/nexus/content/repositories/releases/" 320 | ``` 321 | 322 | ### How to start in dev mode 323 | 324 | To start it's enough to run the following Gradle Command 325 | 326 | ``` 327 | ./gradlew bootRun -Dspring.profiles.active=DEV -DAPP_ENV=dev 328 | ``` 329 | 330 | # Working example of the whole setup 331 | 332 | [Link to the Github organization with proper setup](https://github.com/2015-06-devoxx-microservices) 333 | 334 | -------------------------------------------------------------------------------- /hackathons/docs/microhackathon-test.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microservice-hackathon/infrastructure/0aa687a095b84cb2490f894f681bd19de1355003/hackathons/docs/microhackathon-test.md -------------------------------------------------------------------------------- /hackathons/docs/uservices-hackathon.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microservice-hackathon/infrastructure/0aa687a095b84cb2490f894f681bd19de1355003/hackathons/docs/uservices-hackathon.md -------------------------------------------------------------------------------- /hackathons/microhackathon-test.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | domain: uservices.pl 4 | github_organization: microhackathon-test 5 | docs_title: "Microservice Hackathon - TEST" 6 | 7 | docs: 8 | - name: "{{ github_organization }}.github.io" 9 | template: https://github.com/microservice-hackathon/docs-template.git 10 | template_version: master 11 | 12 | properties: 13 | - name: "properties" 14 | 15 | projects: 16 | 17 | - name: ui-waw 18 | port: 8052 19 | template: https://github.com/4finance/boot-microservice.git 20 | template_version: boot-microservice-gui-without-node 21 | 22 | - name: fraud-detection-service-waw 23 | port: 8053 24 | template: https://github.com/4finance/boot-microservice.git 25 | template_version: master 26 | 27 | - name: loan-application-service-waw 28 | port: 8054 29 | template: https://github.com/4finance/boot-microservice.git 30 | template_version: master 31 | 32 | - name: loan-application-decision-maker-waw 33 | port: 8055 34 | template: https://github.com/4finance/boot-microservice.git 35 | template_version: master 36 | 37 | - name: marketing-offer-generator-waw 38 | port: 8056 39 | template: https://github.com/4finance/boot-microservice.git 40 | template_version: master 41 | 42 | - name: reporting-service-waw 43 | port: 8057 44 | template: https://github.com/4finance/boot-microservice.git 45 | template_version: boot-microservice-gui-without-node 46 | 47 | - name: client-service-waw 48 | port: 8058 49 | template: https://github.com/4finance/boot-microservice.git 50 | template_version: boot-microservice-gui-without-node 51 | 52 | - name: ui-lodz 53 | port: 9052 54 | template: https://github.com/4finance/boot-microservice.git 55 | template_version: boot-microservice-gui-without-node 56 | 57 | - name: fraud-detection-service-lodz 58 | port: 9053 59 | template: https://github.com/4finance/boot-microservice.git 60 | template_version: master 61 | 62 | - name: loan-application-service-lodz 63 | port: 9054 64 | template: https://github.com/4finance/boot-microservice.git 65 | template_version: master 66 | 67 | - name: loan-application-decision-maker-lodz 68 | port: 9055 69 | template: https://github.com/4finance/boot-microservice.git 70 | template_version: master 71 | 72 | - name: marketing-offer-generator-lodz 73 | port: 9056 74 | template: https://github.com/4finance/boot-microservice.git 75 | template_version: master 76 | 77 | - name: reporting-service-lodz 78 | port: 9057 79 | template: https://github.com/4finance/boot-microservice.git 80 | template_version: boot-microservice-gui-without-node 81 | 82 | - name: client-service-lodz 83 | port: 9058 84 | template: https://github.com/4finance/boot-microservice.git 85 | template_version: boot-microservice-gui-without-node 86 | -------------------------------------------------------------------------------- /hackathons/uservices-hackathon.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | domain: uservices.pl 4 | github_organization: uservices-hackathon 5 | docs_title: "Microservices Hackathon" 6 | 7 | docs: 8 | - name: "{{ github_organization }}.github.io" 9 | template: ssh://git@github.com/microservice-hackathon/docs-template.git 10 | template_version: master 11 | 12 | properties: 13 | - name: "properties" 14 | template: ssh://git@github.com/2015-06-devoxx-microservices/properties.git 15 | 16 | projects: 17 | 18 | - name: aggregatr.io 19 | port: 9090 20 | template: ssh://git@github.com/2015-06-devoxx-microservices/aggregatr.io.git 21 | 22 | - name: butelkatr.io 23 | port: 9091 24 | template: ssh://git@github.com/2015-06-devoxx-microservices/butelkatr.io.git 25 | 26 | - name: dojrzewatr.io 27 | port: 9092 28 | template: ssh://git@github.com/2015-06-devoxx-microservices/dojrzewatr.io.git 29 | 30 | - name: prezentatr.io 31 | port: 9093 32 | template: ssh://git@github.com/2015-06-devoxx-microservices/prezentatr.io.git 33 | -------------------------------------------------------------------------------- /roles/apache/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | apache_modules: 4 | - headers 5 | -------------------------------------------------------------------------------- /roles/apache/files/allow-srv.conf: -------------------------------------------------------------------------------- 1 | 2 | Options Indexes FollowSymLinks 3 | AllowOverride None 4 | Require all granted 5 | 6 | -------------------------------------------------------------------------------- /roles/apache/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: reload apache 4 | service: name=apache2 state=reloaded 5 | 6 | - name: restart apache 7 | service: name=apache2 state=restarted 8 | 9 | - name: enable apache 10 | service: name=apache2 enabled=yes 11 | 12 | -------------------------------------------------------------------------------- /roles/apache/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: install apache packages 4 | apt: name={{ item }} state=present update_cache=yes 5 | with_items: 6 | - apache2-mpm-worker 7 | notify: 8 | - enable apache 9 | 10 | - name: allow access to /srv 11 | copy: 12 | src: allow-srv.conf 13 | dest: /etc/apache2/conf-available/allow-srv.conf 14 | 15 | - name: allow access to /srv 16 | command: > 17 | a2enconf allow-srv 18 | register: a2enconf 19 | changed_when: '"To activate the new configuration" in a2enconf.stdout' 20 | notify: 21 | - restart apache 22 | 23 | - name: enable modules 24 | command: > 25 | a2enmod {{ item }} 26 | register: a2enmod 27 | changed_when: '"To activate the new configuration" in a2enconf.stdout' 28 | with_items: apache_modules 29 | notify: 30 | - restart apache 31 | -------------------------------------------------------------------------------- /roles/common/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | common_download_dir: /var/cache/ansible/download 4 | -------------------------------------------------------------------------------- /roles/common/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: install common packages 4 | apt: pkg={{ item }} update_cache=yes state=present 5 | with_items: 6 | - python-pycurl 7 | - python-apt 8 | - vim-nox 9 | - mc 10 | - htop 11 | - ntp 12 | - less 13 | - ncurses-term 14 | - git 15 | - screen 16 | 17 | - name: create common directory for downloads 18 | file: dest={{ common_download_dir }} state=directory 19 | -------------------------------------------------------------------------------- /roles/deploy/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | deploy_user: root 4 | deploy_rundeck_public_key: "" 5 | -------------------------------------------------------------------------------- /roles/deploy/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: add rundeck's public key to deploy user 4 | authorized_key: 5 | user: "{{ deploy_user }}" 6 | key: "{{ lookup('file', deploy_rundeck_public_key) }}" 7 | -------------------------------------------------------------------------------- /roles/elasticsearch/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | elasticsearch_version: "1.6" 4 | -------------------------------------------------------------------------------- /roles/elasticsearch/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: restart elasticsearch 4 | service: 5 | name: elasticsearch 6 | state: restarted 7 | -------------------------------------------------------------------------------- /roles/elasticsearch/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: enable elasticsearch repository 4 | apt_repository: 5 | repo: "deb http://packages.elasticsearch.org/elasticsearch/{{ elasticsearch_version }}/debian stable main" 6 | state: present 7 | 8 | - name: add elasticsearch repo key 9 | apt_key: 10 | url: http://packages.elasticsearch.org/GPG-KEY-elasticsearch 11 | state: present 12 | 13 | - name: install required packages 14 | apt: 15 | pkg: "{{ item }}" 16 | state: present 17 | update_cache: yes 18 | with_items: 19 | - openjdk-7-jre 20 | - elasticsearch 21 | 22 | - name: enable CORS (required by Kibana 3) 23 | lineinfile: 24 | dest: /etc/elasticsearch/elasticsearch.yml 25 | line: "{{ item }}" 26 | state: present 27 | with_items: 28 | - 'http.cors.enabled: true' 29 | - 'http.cors.allow-origin: "/.*/"' 30 | notify: 31 | - restart elasticsearch 32 | 33 | - name: start and enable elasticsearch service 34 | service: 35 | name: elasticsearch 36 | state: started 37 | enabled: yes 38 | -------------------------------------------------------------------------------- /roles/github_repo/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | github_repo_temp: "/tmp/{{ hackathon_edition }}" 4 | -------------------------------------------------------------------------------- /roles/github_repo/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: check if repository exists 4 | command: > 5 | curl -u {{ github_repo_user }}:{{ github_repo_token }} 6 | https://api.github.com/repos/{{ github_repo_organization }}/{{ item.name }} 7 | register: curl_result 8 | with_items: github_repo_projects 9 | changed_when: false 10 | 11 | - name: create temporary directory 12 | file: 13 | dest: "{{ github_repo_temp }}" 14 | state: directory 15 | 16 | - name: create repository on Github 17 | command: > 18 | curl -u {{ github_repo_user }}:{{ github_repo_token }} 19 | https://api.github.com/orgs/{{ github_repo_organization }}/repos 20 | -d '{ "name" : "{{ item.0.name }}" }' 21 | when: "'Not Found' in item.1.stdout" 22 | with_together: 23 | - github_repo_projects 24 | - curl_result.results 25 | 26 | - name: clone source repository 27 | git: 28 | repo: "{{ item.0.template }}" 29 | version: "{{ item.0.template_version|default('master') }}" 30 | dest: "{{ github_repo_temp }}/{{ item.0.name }}" 31 | when: "'Not Found' in item.1.stdout and item.0.template is defined" 32 | with_together: 33 | - github_repo_projects 34 | - curl_result.results 35 | 36 | - name: remove origin 37 | command: > 38 | git remote remove origin 39 | chdir="{{ github_repo_temp }}/{{ item.0.name }}" 40 | when: "'Not Found' in item.1.stdout and item.0.template is defined" 41 | with_together: 42 | - github_repo_projects 43 | - curl_result.results 44 | 45 | - name: add new origin 46 | command: > 47 | git remote add origin git@github.com:{{ github_repo_organization }}/{{ item.0.name }}.git 48 | chdir="{{ github_repo_temp }}/{{ item.0.name }}" 49 | when: "'Not Found' in item.1.stdout and item.0.template is defined" 50 | with_together: 51 | - github_repo_projects 52 | - curl_result.results 53 | 54 | - name: push code to new repository 55 | command: > 56 | git push -u origin {{ item.0.template_version|default('master') }}:master 57 | chdir="{{ github_repo_temp }}/{{ item.0.name }}" 58 | when: "'Not Found' in item.1.stdout and item.0.template is defined" 59 | with_together: 60 | - github_repo_projects 61 | - curl_result.results 62 | 63 | - name: push tags to new repository 64 | command: > 65 | git push --tags 66 | chdir="{{ github_repo_temp }}/{{ item.0.name }}" 67 | when: "'Not Found' in item.1.stdout and item.0.template is defined" 68 | with_together: 69 | - github_repo_projects 70 | - curl_result.results 71 | 72 | - name: remove temp directory 73 | file: 74 | dest: "{{ github_repo_temp }}" 75 | state: absent 76 | -------------------------------------------------------------------------------- /roles/github_repo_docs/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | github_repo_docs_temp: "/tmp/{{ hackathon_edition }}" 4 | -------------------------------------------------------------------------------- /roles/github_repo_docs/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: create temporary directory 4 | file: 5 | dest: "{{ github_repo_docs_temp }}" 6 | state: directory 7 | 8 | - name: clone source repository 9 | git: 10 | repo: "git@github.com:{{ github_repo_docs_organization }}/{{ github_repo_docs_organization }}.github.io.git" 11 | dest: "{{ github_repo_docs_temp }}/{{ github_repo_docs_organization }}.github.io" 12 | 13 | - name: copy docs.md 14 | copy: 15 | src: hackathons/docs/{{ hackathon_edition }}.md 16 | dest: "{{ github_repo_docs_temp }}/{{ github_repo_docs_organization }}.github.io/_includes/docs.md" 17 | 18 | - name: create tools list 19 | copy: 20 | dest: "{{ github_repo_docs_temp }}/{{ github_repo_docs_organization }}.github.io/_data/tools.yml" 21 | content: "{{ github_repo_docs_tools|to_nice_yaml }}" 22 | 23 | - name: create projects list 24 | copy: 25 | dest: "{{ github_repo_docs_temp }}/{{ github_repo_docs_organization }}.github.io/_data/projects.yml" 26 | content: "{{ github_repo_docs_projects|to_nice_yaml }}" 27 | 28 | - name: create configuration file 29 | template: 30 | src: _config.yml.j2 31 | dest: "{{ github_repo_docs_temp }}/{{ github_repo_docs_organization }}.github.io/_config.yml" 32 | 33 | - name: stage changes 34 | command: > 35 | git add -A 36 | chdir="{{ github_repo_docs_temp }}/{{ github_repo_docs_organization }}.github.io" 37 | ignore_errors: yes 38 | 39 | - name: commit changes 40 | command: > 41 | git commit -m "Update docs" 42 | chdir="{{ github_repo_docs_temp }}/{{ github_repo_docs_organization }}.github.io" 43 | ignore_errors: yes 44 | 45 | - name: push code to new repository 46 | command: > 47 | git push -u origin master 48 | chdir="{{ github_repo_docs_temp }}/{{ github_repo_docs_organization }}.github.io" 49 | -------------------------------------------------------------------------------- /roles/github_repo_docs/templates/_config.yml.j2: -------------------------------------------------------------------------------- 1 | title: {{ docs_title }} 2 | url: "http://{{ github_organization }}.github.io" 3 | markdown: redcarpet 4 | exclude: ['vendor'] 5 | domain: {{ domain }} 6 | -------------------------------------------------------------------------------- /roles/github_repo_microservice/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | github_repo_microservice_temp: "/tmp/{{ hackathon_edition }}" 4 | -------------------------------------------------------------------------------- /roles/github_repo_microservice/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: create temporary directory 4 | file: 5 | dest: "{{ github_repo_microservice_temp }}" 6 | state: directory 7 | 8 | - name: clone source repository 9 | git: 10 | repo: "git@github.com:{{ github_repo_microservice_organization }}/{{ item.name }}.git" 11 | dest: "{{ github_repo_microservice_temp }}/{{ item.name }}" 12 | with_items: 13 | github_repo_microservice_projects 14 | 15 | - name: update gradle.properties 16 | replace: 17 | dest: "{{ github_repo_microservice_temp }}/{{ item.name }}/gradle.properties" 18 | regexp: '^mavenRepoUrl=.*$' 19 | replace: 'mavenRepoUrl={{ nexus_url }}/content/repositories/releases/' 20 | with_items: 21 | github_repo_microservice_projects 22 | 23 | - name: update gradle.properties 24 | replace: 25 | dest: "{{ github_repo_microservice_temp }}/{{ item.name }}/gradle.properties" 26 | regexp: '^mavenUser=.*$' 27 | replace: 'mavenUser=admin' 28 | with_items: 29 | github_repo_microservice_projects 30 | 31 | - name: update gradle.properties 32 | replace: 33 | dest: "{{ github_repo_microservice_temp }}/{{ item.name }}/gradle.properties" 34 | regexp: '^mavenPassword=.*$' 35 | replace: 'mavenPassword=admin123' 36 | with_items: 37 | github_repo_microservice_projects 38 | 39 | - name: update settings.gradle 40 | replace: 41 | dest: "{{ github_repo_microservice_temp }}/{{ item.name }}/settings.gradle" 42 | regexp: '^rootProject.name =.*$' 43 | replace: 'rootProject.name = "{{ item.name }}"' 44 | with_items: 45 | github_repo_microservice_projects 46 | 47 | - name: commit changes 48 | command: > 49 | git commit -a -m "Update configuration" 50 | chdir="{{ github_repo_microservice_temp }}/{{ item.name }}" 51 | ignore_errors: yes 52 | with_items: 53 | github_repo_microservice_projects 54 | 55 | - name: push code to new repository 56 | command: > 57 | git push -u origin master 58 | chdir="{{ github_repo_microservice_temp }}/{{ item.name }}" 59 | with_items: 60 | github_repo_microservice_projects 61 | -------------------------------------------------------------------------------- /roles/github_repo_microservice/templates/application.yaml.j2: -------------------------------------------------------------------------------- 1 | 2 | spring: 3 | jackson.deserialization.fail-on-unknown-properties: false 4 | groovy.template.check-template-location: false 5 | 6 | rest.api.version: 1.0 7 | city.finding.service.url: "http://api.openweathermap.org/data/2.5/weather" 8 | 9 | graphite: 10 | host: {{ graphite_host }} 11 | 12 | metrics.path: 13 | country: pl 14 | app: {{ item.name }} 15 | 16 | stubrunner.stubs: 17 | repository.root: "{{ nexus_url }}/content/repositories/releases/" 18 | group: com.ofg 19 | module: stub-definitions 20 | 21 | server: 22 | port: {{ item.port }} 23 | -------------------------------------------------------------------------------- /roles/github_repo_microservice/templates/microservice.json.j2: -------------------------------------------------------------------------------- 1 | { 2 | "{{ item.name.split('-')[-1] }}": { 3 | "this": "com/ofg/{{ item.name }}", 4 | "dependencies": { 5 | "collerator": { 6 | "path": "com/ofg/some-other-service" 7 | } 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /roles/github_repo_properties/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | github_repo_properties_temp: "/tmp/{{ hackathon_edition }}" 4 | -------------------------------------------------------------------------------- /roles/github_repo_properties/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: create temporary directory 4 | file: 5 | dest: "{{ github_repo_properties_temp }}" 6 | state: directory 7 | 8 | - name: clone source repository 9 | git: 10 | repo: "git@github.com:{{ github_repo_properties_organization }}/properties.git" 11 | dest: "{{ github_repo_properties_temp }}/properties" 12 | update: no 13 | 14 | - name: stage changes 15 | command: > 16 | git add . 17 | chdir="{{ github_repo_properties_temp }}/properties" 18 | ignore_errors: yes 19 | 20 | - name: commit changes 21 | command: > 22 | git commit -a -m "Update configuration" 23 | chdir="{{ github_repo_properties_temp }}/properties" 24 | ignore_errors: yes 25 | 26 | - name: push code to new repository 27 | command: > 28 | git push -u origin master 29 | chdir="{{ github_repo_properties_temp }}/properties" 30 | -------------------------------------------------------------------------------- /roles/github_repo_properties/templates/application.yaml.j2: -------------------------------------------------------------------------------- 1 | metrics.path: 2 | country: {{ item.name.split('-')[-1] }} 3 | app: {{ item.name }} 4 | 5 | server: 6 | port: {{ item.port }} 7 | 8 | -------------------------------------------------------------------------------- /roles/github_repo_properties/templates/global.yaml.j2: -------------------------------------------------------------------------------- 1 | 2 | spring: 3 | jackson.deserialization.fail-on-unknown-properties: false 4 | groovy.template.check-template-location: false 5 | 6 | rest.api.version: 1.0 7 | city.finding.service.url: "http://api.openweathermap.org/data/2.5/weather" 8 | 9 | request.payload.logging.maxlength: 2000 10 | 11 | graphite: 12 | host: {{ graphite_host }} 13 | 14 | metrics: 15 | path: 16 | environment: prod 17 | 18 | stubrunner.stubs: 19 | repository.root: "{{ nexus_url }}/content/repositories/releases/" 20 | group: com.ofg 21 | module: stub-definitions 22 | -------------------------------------------------------------------------------- /roles/grafana/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | grafana_git_url: https://github.com/torkelo/grafana.git 4 | grafana_root: /srv/grafana 5 | grafana_version: 1.6.1 6 | grafana_vhost_server_name: grafana 7 | grafana_port: 8080 8 | 9 | grafana_elasticsearch_url: http://{{ elasticsearch_host }}:9200 10 | grafana_graphite_url: http://{{ graphite_host }} 11 | 12 | -------------------------------------------------------------------------------- /roles/grafana/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: create grafana directories 4 | file: 5 | dest: "{{ item }}" 6 | state: directory 7 | with_items: 8 | - "{{ grafana_root }}" 9 | - "{{ grafana_root }}/dist" 10 | 11 | - name: download grafana 12 | get_url: 13 | url: "http://grafanarel.s3.amazonaws.com/grafana-{{ grafana_version }}.tar.gz" 14 | dest: "{{ grafana_root }}/dist/grafana-{{ grafana_version }}.tar.gz" 15 | 16 | - name: extract grafana tarball 17 | command: > 18 | tar -zxvf {{ grafana_root}}/dist/grafana-{{ grafana_version }}.tar.gz -C {{ grafana_root}} 19 | args: 20 | creates: "{{ grafana_root}}/grafana-{{ grafana_version }}" 21 | 22 | - name: link grafana version 23 | file: 24 | path: "{{ grafana_root }}/current" 25 | src: "{{ grafana_root }}/grafana-{{ grafana_version }}" 26 | state: link 27 | 28 | - name: create config file 29 | template: 30 | src: "grafana.js.j2" 31 | dest: "{{grafana_root}}/grafana-{{grafana_version}}/config.js" 32 | mode: "u=rw,g=r,o=r" 33 | 34 | - name: create apache vhost 35 | template: 36 | src: grafana-vhost.j2 37 | dest: /etc/apache2/sites-available/grafana.conf 38 | mode: "u=rw,g=r,o=r" 39 | notify: 40 | - restart apache 41 | 42 | - name: enable apache vhost 43 | command: > 44 | a2ensite grafana 45 | register: a2ensite 46 | changed_when: '"To activate the new configuration" in a2ensite.stdout' 47 | notify: 48 | - restart apache 49 | -------------------------------------------------------------------------------- /roles/grafana/templates/grafana-vhost.j2: -------------------------------------------------------------------------------- 1 | 2 | NameVirtualHost *:80 3 | 4 | 5 | 6 | DocumentRoot {{ grafana_root }}/current 7 | ServerName {{ grafana_host }} 8 | 9 | 10 | Options Indexes FollowSymLinks MultiViews 11 | AllowOverride None 12 | Order allow,deny 13 | allow from all 14 | 15 | 16 | ErrorLog ${APACHE_LOG_DIR}/grafana_error.log 17 | LogLevel warn 18 | CustomLog ${APACHE_LOG_DIR}/grafana_access.log combined 19 | 20 | 21 | -------------------------------------------------------------------------------- /roles/grafana/templates/grafana.js.j2: -------------------------------------------------------------------------------- 1 | define(['settings'], 2 | function (Settings) { 3 | "use strict"; 4 | 5 | return new Settings({ 6 | 7 | // datasources, you can add multiple 8 | datasources: { 9 | graphite: { 10 | type: 'graphite', 11 | url: "{{ grafana_graphite_url }}", 12 | default: true 13 | } 14 | }, 15 | 16 | // elasticsearch url 17 | // used for storing and loading dashboards, optional 18 | // For Basic authentication use: http://username:password@domain.com:9200 19 | elasticsearch: "{{ grafana_elasticsearch_url }}", 20 | 21 | // default start dashboard 22 | default_route: '/dashboard/file/default.json', 23 | 24 | // Elasticsearch index for storing dashboards 25 | grafana_index: "grafana-dashboard", 26 | 27 | // timezoneOFfset: 28 | // If you experiance problems with zoom, it is probably caused by timezone diff between 29 | // your browser and the graphite-web application. timezoneOffset setting can be used to have Grafana 30 | // translate absolute time ranges to the graphite-web timezone. 31 | // Example: 32 | // If TIME_ZONE in graphite-web config file local_settings.py is set to America/New_York, then set 33 | // timezoneOffset to "-0500" (for UTC - 5 hours) 34 | // Example: 35 | // If TIME_ZONE is set to UTC, set this to "0000" 36 | // 37 | timezoneOffset: null, 38 | 39 | // set to false to disable unsaved changes warning 40 | unsaved_changes_warning: true, 41 | 42 | // set the default timespan for the playlist feature 43 | // Example: "1m", "1h" 44 | playlist_timespan: "1m", 45 | 46 | // Add your own custom pannels 47 | plugins: { 48 | panels: [] 49 | } 50 | 51 | }); 52 | }); 53 | -------------------------------------------------------------------------------- /roles/graphite/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | graphite_host: graphite.example.com 4 | -------------------------------------------------------------------------------- /roles/graphite/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: restart carbon-cache 4 | service: 5 | name: carbon-cache 6 | state: restarted 7 | 8 | - name: restart apache2 9 | service: 10 | name: apache2 11 | state: restarted 12 | -------------------------------------------------------------------------------- /roles/graphite/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: install required packages 4 | apt: 5 | name: "{{ item }}" 6 | state: present 7 | update_cache: yes 8 | with_items: 9 | - apache2 10 | - libapache2-mod-wsgi 11 | - graphite-carbon 12 | - graphite-web 13 | 14 | - name: check if graphite db exists 15 | stat: 16 | path: "{{ graphite_db_file }}" 17 | register: graphite_db_file_stat 18 | changed_when: false 19 | 20 | - name: create graphtie db 21 | shell: > 22 | rm -f {{ graphite_db_file }} && /usr/bin/graphite-manage syncdb --noinput 23 | when: graphite_db_file_stat.stat.exists == false or graphite_db_file_stat.stat.size == 0 24 | 25 | - name: set permissions for graphite db 26 | file: 27 | dest: "{{ graphite_db_file }}" 28 | owner: "{{ graphite_user }}" 29 | group: "{{ graphite_group }}" 30 | 31 | - name: create apache vhost 32 | template: 33 | src: graphite-vhost.j2 34 | dest: /etc/apache2/sites-available/graphite-web.conf 35 | mode: "u=rw,g=r,o=r" 36 | notify: 37 | - restart apache2 38 | 39 | - name: enable modules 40 | command: a2enmod wsgi 41 | register: a2enmod 42 | changed_when: '"To activate the new configuration" in a2enmod.stdout' 43 | notify: 44 | - restart apache2 45 | 46 | - name: enable graphite-web site 47 | command: a2ensite graphite-web 48 | register: a2ensite 49 | changed_when: '"To activate the new configuration" in a2ensite.stdout' 50 | notify: 51 | - restart apache2 52 | -------------------------------------------------------------------------------- /roles/graphite/templates/graphite-vhost.j2: -------------------------------------------------------------------------------- 1 | 2 | 3 | ServerName {{ graphite_host }} 4 | WSGIDaemonProcess _graphite processes=5 threads=5 display-name='%{GROUP}' inactivity-timeout=120 user={{ graphite_user }} group={{ graphite_group }} 5 | WSGIProcessGroup {{ graphite_group }} 6 | WSGIImportScript /usr/share/graphite-web/graphite.wsgi process-group={{ graphite_group }} application-group=%{GLOBAL} 7 | WSGIScriptAlias / /usr/share/graphite-web/graphite.wsgi 8 | 9 | Header set Access-Control-Allow-Origin "*" 10 | Header set Access-Control-Allow-Methods "GET,OPTIONS" 11 | Header set Access-Control-Allow-Headers "origin, authorization, accept" 12 | 13 | Alias /content/ /usr/share/graphite-web/static/ 14 | 15 | SetHandler None 16 | 17 | 18 | ErrorLog ${APACHE_LOG_DIR}/graphite-web_error.log 19 | 20 | # Possible values include: debug, info, notice, warn, error, crit, 21 | # alert, emerg. 22 | LogLevel warn 23 | 24 | CustomLog ${APACHE_LOG_DIR}/graphite-web_access.log combined 25 | 26 | 27 | -------------------------------------------------------------------------------- /roles/graphite/vars/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | # default user and group in Debian GNU/Linux 4 | graphite_user: _graphite 5 | graphite_group: _graphite 6 | 7 | # default db location 8 | graphite_db_file: /var/lib/graphite/graphite.db 9 | -------------------------------------------------------------------------------- /roles/hystrix_dashboard/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | hystrix_dashboard_tomcat_http_port: 8090 4 | hystrix_dashboard_version: 1.4.11 5 | 6 | hystrix_dashboard_turbine_version: 1.0.0 7 | 8 | -------------------------------------------------------------------------------- /roles/hystrix_dashboard/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: restart tomcat7 4 | service: 5 | name: tomcat7 6 | state: restarted 7 | -------------------------------------------------------------------------------- /roles/hystrix_dashboard/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: install tomcat7 package 4 | apt: 5 | pkg: tomcat7 6 | state: present 7 | update_cache: yes 8 | 9 | - name: configure tomcat7 10 | template: 11 | src: server.xml.j2 12 | dest: /etc/tomcat7/server.xml 13 | owner: root 14 | group: tomcat7 15 | mode: "0644" 16 | notify: 17 | - restart tomcat7 18 | 19 | - name: deploy hystrix-dashboard 20 | get_url: 21 | url: "{{ hystrix_dashboard_download_url }}" 22 | dest: "/var/lib/tomcat7/webapps/hystrix-dashboard.war" 23 | owner: tomcat7 24 | group: tomcat7 25 | mode: "0644" 26 | notify: 27 | - restart tomcat7 28 | 29 | - name: deploy turbine 30 | get_url: 31 | url: "{{ hystrix_dashboard_turbine_download_url }}" 32 | dest: "/var/lib/tomcat7/webapps/turbine.war" 33 | owner: tomcat7 34 | group: tomcat7 35 | mode: "0644" 36 | notify: 37 | - restart tomcat7 38 | -------------------------------------------------------------------------------- /roles/hystrix_dashboard/templates/server.xml.j2: -------------------------------------------------------------------------------- 1 | 2 | 18 | 22 | 23 | 26 | 27 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 40 | 41 | 44 | 49 | 50 | 51 | 56 | 57 | 58 | 59 | 63 | 64 | 65 | 72 | 76 | 77 | 83 | 88 | 93 | 94 | 95 | 98 | 99 | 100 | 105 | 106 | 109 | 110 | 111 | 114 | 117 | 118 | 120 | 121 | 125 | 127 | 128 | 129 | 131 | 132 | 134 | 137 | 138 | 141 | 144 | 145 | 146 | 147 | 148 | 149 | -------------------------------------------------------------------------------- /roles/hystrix_dashboard/vars/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | hystrix_dashboard_download_url: "https://repo1.maven.org/maven2/com/netflix/hystrix/hystrix-dashboard/{{ hystrix_dashboard_version }}/hystrix-dashboard-{{ hystrix_dashboard_version }}.war" 4 | hystrix_dashboard_turbine_download_url: "https://github.com/downloads/Netflix/Turbine/turbine-web-{{ hystrix_dashboard_turbine_version }}.war" 5 | -------------------------------------------------------------------------------- /roles/jenkins/.travis.yml: -------------------------------------------------------------------------------- 1 | --- 2 | language: python 3 | python: "2.7" 4 | 5 | env: 6 | - SITE=test.yml 7 | 8 | before_install: 9 | - sudo apt-get update -qq 10 | - sudo apt-get install -y curl 11 | 12 | install: 13 | # Install Ansible. 14 | - pip install ansible 15 | 16 | # Add ansible.cfg to pick up roles path. 17 | - "{ echo '[defaults]'; echo 'roles_path = ../'; } >> ansible.cfg" 18 | 19 | # Install required dependencies. 20 | - ansible-galaxy install geerlingguy.java 21 | 22 | script: 23 | # Check the role/playbook's syntax. 24 | - "ansible-playbook -i tests/inventory tests/$SITE --syntax-check" 25 | 26 | # Run the role/playbook with ansible-playbook. 27 | - "ansible-playbook -i tests/inventory tests/$SITE --connection=local --sudo" 28 | 29 | # Run the role/playbook again, checking to make sure it's idempotent. 30 | - > 31 | ansible-playbook -i tests/inventory tests/$SITE --connection=local --sudo 32 | | grep -q 'changed=0.*failed=0' 33 | && (echo 'Idempotence test: pass' && exit 0) 34 | || (echo 'Idempotence test: fail' && exit 1) 35 | 36 | # Make sure Jenkins is running. 37 | # TODO 38 | -------------------------------------------------------------------------------- /roles/jenkins/README.md: -------------------------------------------------------------------------------- 1 | # Ansible Role: Jenkins CI 2 | 3 | [![Build Status](https://travis-ci.org/geerlingguy/ansible-role-jenkins.svg?branch=master)](https://travis-ci.org/geerlingguy/ansible-role-jenkins) 4 | 5 | Installs Jenkins CI on RHEL/CentOS and Debian/Ubuntu servers. 6 | 7 | ## Requirements 8 | 9 | None. 10 | 11 | ## Role Variables 12 | 13 | Available variables are listed below, along with default values (see `vars/main.yml`): 14 | 15 | hostname: localhost 16 | 17 | The system hostname; usually `localhost` works fine. This will be used during setup to communicate with the running Jenkins instance via HTTP requests. 18 | 19 | jenkins_jar_location: /opt/jenkins-cli.jar 20 | 21 | The location at which the `jenkins-cli.jar` jarfile will be kept. This is used for communicating with Jenkins via the CLI. 22 | 23 | jenkins_plugins: 24 | - git 25 | - sonar 26 | - ssh 27 | 28 | Jenkins plugins to be installed automatically during provisioning. You can always install more plugins via the Jenkins UI at a later time, but this is helpful in getting things up and running more quickly. 29 | 30 | ## Dependencies 31 | 32 | - geerlingguy.java 33 | 34 | ## Example Playbook 35 | 36 | - hosts: ci-server 37 | vars: 38 | hostname: jenkins-example.com 39 | roles: 40 | - { role: geerlingguy.jenkins } 41 | 42 | ## License 43 | 44 | MIT / BSD 45 | 46 | ## Author Information 47 | 48 | This role was created in 2014 by [Jeff Geerling](http://jeffgeerling.com/), author of [Ansible for DevOps](http://ansiblefordevops.com/). 49 | -------------------------------------------------------------------------------- /roles/jenkins/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | hostname: localhost 3 | jenkins_jar_location: /opt/jenkins-cli.jar 4 | jenkins_plugins: 5 | - git 6 | - sonar 7 | - ssh 8 | - gradle 9 | - greenballs 10 | - rundeck 11 | - delivery-pipeline-plugin 12 | - build-pipeline-plugin 13 | - job-dsl 14 | - nested-view 15 | - parameterized-trigger 16 | - compact-columns 17 | - extra-columns 18 | - thinBackup 19 | - timestamper 20 | - jobConfigHistory 21 | - envinject 22 | - ghprb 23 | - stash-pullrequest-builder 24 | - stashNotifier 25 | - plain-credentials 26 | - credentials-binding 27 | - build-name-setter 28 | - build-monitor-plugin 29 | - claim 30 | - build-timeout 31 | - email-ext 32 | - rebuild 33 | - heavy-job 34 | - buildgraph-view 35 | - JDK_Parameter_Plugin 36 | - git-parameter 37 | - downstream-buildview 38 | - mask-passwords 39 | - repository-connector 40 | - dashboard-view 41 | - global-build-stats 42 | - groovy 43 | - groovy-postbuild 44 | - build-flow-plugin 45 | - extensible-choice-parameter 46 | - jenkins-multijob-plugin 47 | - dynamicparameter 48 | - pegdown-formatter 49 | - swarm 50 | - violation-comments-to-stash 51 | - violations 52 | - next-build-number 53 | - slack 54 | - checkstyle 55 | -------------------------------------------------------------------------------- /roles/jenkins/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: restart jenkins 3 | service: name=jenkins state=restarted 4 | -------------------------------------------------------------------------------- /roles/jenkins/meta/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | galaxy_info: 3 | author: geerlingguy 4 | description: Jenkins CI 5 | company: "Midwestern Mac, LLC" 6 | license: "license (BSD, MIT)" 7 | min_ansible_version: 1.4 8 | platforms: 9 | - name: EL 10 | versions: 11 | - 6 12 | - 7 13 | - name: Debian 14 | versions: 15 | - all 16 | - name: Ubuntu 17 | versions: 18 | - all 19 | categories: 20 | - development 21 | - packaging 22 | -------------------------------------------------------------------------------- /roles/jenkins/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Setup/install tasks. 3 | - include: setup-RedHat.yml 4 | when: ansible_os_family == 'RedHat' 5 | 6 | - include: setup-Debian.yml 7 | when: ansible_os_family == 'Debian' 8 | 9 | # Make sure Jenkins starts, then configure Jenkins. 10 | - name: Ensure Jenkins is started and runs on startup. 11 | service: name=jenkins state=started enabled=yes 12 | 13 | - name: Wait for Jenkins to start up before proceeding. 14 | wait_for: 15 | host: "{{ hostname }}" 16 | port: 8080 17 | timeout: 600 18 | 19 | - name: Get the jenkins-cli jarfile from the Jenkins server. 20 | get_url: 21 | url: "http://{{ hostname }}:8080/jnlpJars/jenkins-cli.jar" 22 | dest: "{{ jenkins_jar_location }}" 23 | register: jarfile_get 24 | until: "'OK' in jarfile_get.msg or 'file already exists' in jarfile_get.msg" 25 | retries: 15 26 | delay: 10 27 | 28 | # Update Jenkins and install configured plugins. 29 | - include: plugins.yml 30 | -------------------------------------------------------------------------------- /roles/jenkins/tasks/plugins.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Jenkins doesn't allow updates via CLI, though that is required before plugins 3 | # can be installed via CLI. See: https://gist.github.com/rowan-m/1026918 4 | - name: Create Jenkins updates folder. 5 | file: 6 | path: /var/lib/jenkins/updates 7 | owner: jenkins 8 | group: jenkins 9 | mode: 0755 10 | state: directory 11 | 12 | - name: Update Jenkins plugin data. 13 | shell: > 14 | curl -L http://updates.jenkins-ci.org/update-center.json | sed '1d;$d' > /var/lib/jenkins/updates/default.json 15 | creates=/var/lib/jenkins/updates/default.json 16 | 17 | - name: Permissions for default.json updates info. 18 | file: 19 | path: /var/lib/jenkins/updates/default.json 20 | owner: jenkins 21 | group: jenkins 22 | mode: 0755 23 | 24 | - name: Install Jenkins plugins. 25 | command: > 26 | java -jar {{ jenkins_jar_location }} -s http://{{ hostname }}:8080/ install-plugin {{ item }} 27 | creates=/var/lib/jenkins/plugins/{{ item }}.jpi 28 | with_items: jenkins_plugins 29 | notify: restart jenkins 30 | -------------------------------------------------------------------------------- /roles/jenkins/tasks/setup-Debian.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Ensure dependencies are installed. 3 | apt: pkg=curl state=installed 4 | 5 | - name: Add Jenkins apt repository key. 6 | apt_key: 7 | url: "https://jenkins-ci.org/debian/jenkins-ci.org.key" 8 | state: present 9 | 10 | - name: Add Jenkins apt repository. 11 | apt_repository: 12 | repo: "deb http://pkg.jenkins-ci.org/debian binary/" 13 | state: present 14 | update_cache: yes 15 | 16 | - name: Ensure Jenkins is installed. 17 | apt: pkg=jenkins state=installed 18 | -------------------------------------------------------------------------------- /roles/jenkins/tasks/setup-RedHat.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Ensure dependencies are installed. 3 | yum: pkg=curl state=installed 4 | 5 | - name: Ensure Jenkins repo is installed. 6 | get_url: 7 | # LTS repo: http://pkg.jenkins-ci.org/redhat-stable/jenkins.repo 8 | url: http://pkg.jenkins-ci.org/redhat/jenkins.repo 9 | dest: /etc/yum.repos.d/jenkins.repo 10 | 11 | - name: Add Jenkins repo GPG key. 12 | rpm_key: 13 | state: present 14 | # LTS key: http://pkg.jenkins-ci.org/redhat-stable/jenkins-ci.org.key 15 | key: http://pkg.jenkins-ci.org/redhat/jenkins-ci.org.key 16 | 17 | - name: Ensure Jenkins is installed. 18 | yum: pkg=jenkins state=installed 19 | -------------------------------------------------------------------------------- /roles/jenkins/tests/inventory: -------------------------------------------------------------------------------- 1 | localhost 2 | -------------------------------------------------------------------------------- /roles/jenkins/tests/test.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | remote_user: root 4 | roles: 5 | - geerlingguy.java 6 | - ansible-role-jenkins 7 | -------------------------------------------------------------------------------- /roles/jenkins_seed_job/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | jenkins_seed_job_host: localhost 3 | jenkins_seed_job_port: 8080 4 | jenkins_seed_job_cli_client: /tmp/jenkins-cli.jar 5 | 6 | jenkins_seed_job_git_url: https://github.com/microservice-hackathon/jenkins-pipeline-dsl 7 | jenkins_seed_job_git_branch: master 8 | jenkins_seed_job_name: pipeline-seed 9 | -------------------------------------------------------------------------------- /roles/jenkins_seed_job/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: download jenkins-cli 4 | get_url: 5 | url: "http://{{ jenkins_seed_job_host }}:{{ jenkins_seed_job_port }}/jnlpJars/jenkins-cli.jar" 6 | dest: "{{ jenkins_seed_job_cli_client }}" 7 | register: jarfile_get 8 | until: "'OK' in jarfile_get.msg or 'file already exists' in jarfile_get.msg" 9 | retries: 15 10 | delay: 10 11 | 12 | - name: create job configuration 13 | template: 14 | src: job.xml.j2 15 | dest: "/tmp/{{ jenkins_seed_job_name }}.xml" 16 | 17 | - name: create jenkins jobs 18 | shell: > 19 | java -jar {{ jenkins_seed_job_cli_client }} -s http://{{ jenkins_seed_job_host }}:{{ jenkins_seed_job_port}}/ create-job {{ jenkins_seed_job_name }} < /tmp/{{ jenkins_seed_job_name }}.xml 20 | args: 21 | creates: /var/lib/jenkins/jobs/{{ jenkins_seed_job_name }}/config.xml 22 | -------------------------------------------------------------------------------- /roles/jenkins_seed_job/templates/job.xml.j2: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | false 6 | 7 | 2 8 | 9 | 10 | {{ jenkins_seed_job_git_url }} 11 | 12 | 13 | 14 | 15 | {{ jenkins_seed_job_git_branch }} 16 | 17 | 18 | false 19 | 20 | 21 | 22 | 23 | false 24 | 25 | 26 | 27 | 28 | clean lib build 29 | 30 | 31 | (Default) 32 | true 33 | false 34 | true 35 | false 36 | 37 | 38 | jobs/microservice_pipeline.groovy 39 | false 40 | false 41 | DELETE 42 | DELETE 43 | JENKINS_ROOT 44 | lib/*.jar 45 | src/main/resources 46 | src/main/groovy 47 | 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /roles/kibana/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | kibana_dir: /srv/kibana 4 | kibana_port: 80 5 | kibana_version: "3.1.2" 6 | kibana_download_url: "https://download.elasticsearch.org/kibana/kibana/kibana-{{ kibana_version }}.tar.gz" 7 | kibana_host: kibana.example.com 8 | -------------------------------------------------------------------------------- /roles/kibana/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: download archive 4 | get_url: 5 | url: "{{ kibana_download_url }}" 6 | dest: "{{ common_download_dir }}/kibana-{{ kibana_version }}.tar.gz" 7 | 8 | - name: create installation directory 9 | file: 10 | dest: "{{ kibana_dir }}" 11 | state: directory 12 | 13 | - name: unarchive source 14 | unarchive: 15 | src: "{{ common_download_dir }}/kibana-{{ kibana_version }}.tar.gz" 16 | dest: "{{ kibana_dir }}" 17 | copy: no 18 | 19 | - name: create symlink to current version 20 | file: 21 | src: "{{ kibana_dir }}/kibana-{{ kibana_version }}" 22 | dest: "{{ kibana_dir }}/current" 23 | state: link 24 | 25 | - name: create apache vhost 26 | template: 27 | src: kibana-apache-site.j2 28 | dest: /etc/apache2/sites-available/kibana.conf 29 | owner: root 30 | group: root 31 | mode: "u=rw,g=r,o=r" 32 | notify: 33 | - restart apache 34 | 35 | - name: disable default apache site 36 | command: a2dissite 000-default 37 | register: a2dissite 38 | changed_when: '"Site default disabled" in a2dissite.stdout' 39 | notify: 40 | - restart apache 41 | 42 | - name: enable site 43 | command: a2ensite kibana 44 | register: a2ensite 45 | changed_when: '"Enabling site" in a2ensite.stdout' 46 | notify: 47 | - restart apache 48 | -------------------------------------------------------------------------------- /roles/kibana/templates/kibana-apache-site.j2: -------------------------------------------------------------------------------- 1 | 2 | 3 | DocumentRoot {{ kibana_dir }}/current 4 | ServerName {{ kibana_host }} 5 | 6 | 7 | Options Indexes FollowSymLinks 8 | AllowOverride None 9 | Require all granted 10 | 11 | 12 | ErrorLog ${APACHE_LOG_DIR}/kibana_error.log 13 | LogLevel warn 14 | CustomLog ${APACHE_LOG_DIR}/kibana_access.log combined 15 | 16 | 17 | -------------------------------------------------------------------------------- /roles/logstash/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | logstash_version: 1.5 4 | logstash_lumberjack_port: 5043 5 | -------------------------------------------------------------------------------- /roles/logstash/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: restart logstash 4 | service: 5 | name: logstash 6 | state: restarted 7 | -------------------------------------------------------------------------------- /roles/logstash/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: enable logstash repository 4 | apt_repository: 5 | repo: "deb http://packages.elasticsearch.org/logstash/{{ logstash_version }}/debian stable main" 6 | state: present 7 | 8 | - name: add logstash apt key 9 | apt_key: 10 | url: http://packages.elasticsearch.org/GPG-KEY-elasticsearch 11 | state: present 12 | 13 | - name: install logstash package 14 | apt: 15 | pkg: "{{ item }}" 16 | state: present 17 | update_cache: yes 18 | with_items: 19 | - logstash 20 | 21 | - name: create required ssl directory 22 | file: 23 | dest: /etc/logstash/ssl 24 | state: directory 25 | owner: logstash 26 | group: ssl-cert 27 | 28 | - name: copy SSL certificate 29 | copy: 30 | src: "{{ item }}" 31 | dest: "/etc/logstash/ssl/{{ item | basename }}" 32 | owner: logstash 33 | group: ssl-cert 34 | mode: "0600" 35 | with_items: 36 | - files/certs/logstash-forwarder.pem 37 | - files/certs/logstash-forwarder.key 38 | notify: 39 | - restart logstash 40 | 41 | - name: create logstash configuration 42 | template: 43 | src: "{{ item }}" 44 | dest: "/etc/logstash/conf.d/{{ item | basename | replace('.j2', '') }}" 45 | owner: root 46 | group: root 47 | mode: "0644" 48 | with_fileglob: 49 | - ../templates/conf.d/* 50 | notify: 51 | - restart logstash 52 | -------------------------------------------------------------------------------- /roles/logstash/templates/conf.d/01-lumberjack-input.conf.j2: -------------------------------------------------------------------------------- 1 | input { 2 | lumberjack { 3 | port => {{ logstash_lumberjack_port }} 4 | ssl_certificate => "/etc/logstash/ssl/logstash-forwarder.pem" 5 | ssl_key => "/etc/logstash/ssl/logstash-forwarder.key" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /roles/logstash/templates/conf.d/11-java-apps.conf.j2: -------------------------------------------------------------------------------- 1 | filter { 2 | 3 | grok { 4 | match => { "file" => "/srv/deploy/%{DATA:app_name}/logs/*" } 5 | } 6 | 7 | mutate { 8 | gsub => [ 9 | "message", "\$", "-" 10 | ] 11 | add_tag => [ "sanitized" ] 12 | } 13 | 14 | # pattern should match the beginning of the grok match 15 | multiline { 16 | pattern => "(^%{TIMESTAMP_ISO8601})" 17 | what => "previous" 18 | negate => true 19 | } 20 | 21 | # pattern matching logback pattern 22 | grok { 23 | match => { "message" => "(?m)%{TIMESTAMP_ISO8601:timestamp}\s+\|\s+%{LOGLEVEL:severity}\s+\|\s+%{DATA:correlationId}\s+\|\s+%{DATA:thread}\s+\|\s+%{JAVAFILE:class}\s+\|\s+%{GREEDYDATA:shortmessage}" } 24 | } 25 | 26 | # pattern of date in logs 27 | date { 28 | match => [ "timestamp", "yyyy-MM-dd HH:mm:ss.SSSZ" ] 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /roles/logstash/templates/conf.d/21-es-output.conf.j2: -------------------------------------------------------------------------------- 1 | output { 2 | elasticsearch { 3 | host => "127.0.0.1" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /roles/logstash_forwarder/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | logstash_forwarder_path: "/srv/deploy/*/logs/application.log" 4 | -------------------------------------------------------------------------------- /roles/logstash_forwarder/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: restart logstash-forwarder 3 | service: 4 | name: logstash-forwarder 5 | state: restarted 6 | -------------------------------------------------------------------------------- /roles/logstash_forwarder/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: enable logstash repository 4 | apt_repository: 5 | repo: "deb http://packages.elasticsearch.org/logstashforwarder/debian stable main" 6 | state: present 7 | 8 | - name: add logstash apt key 9 | apt_key: 10 | url: http://packages.elasticsearch.org/GPG-KEY-elasticsearch 11 | state: present 12 | 13 | - name: install logstash-forwarder 14 | apt: 15 | pkg: logstash-forwarder 16 | state: present 17 | update_cache: yes 18 | 19 | - name: ensure logstash-forwarder has its SSL certificate 20 | copy: 21 | src: "{{ item }}" 22 | dest: "/etc/ssl/certs/{{ item | basename }}" 23 | owner: root 24 | group: root 25 | with_items: 26 | - files/certs/logstash-forwarder.pem 27 | - files/certs/logstash-forwarder.key 28 | notify: 29 | - restart logstash-forwarder 30 | 31 | - name: ensure logstash-forwarder has its config file 32 | template: 33 | src: logstash-forwarder.conf.j2 34 | dest: /etc/logstash-forwarder.conf 35 | owner: root 36 | group: root 37 | notify: 38 | - restart logstash-forwarder 39 | -------------------------------------------------------------------------------- /roles/logstash_forwarder/templates/logstash-forwarder.conf.j2: -------------------------------------------------------------------------------- 1 | { 2 | 3 | "network": { 4 | "servers": ["{{ logstash_lumberjack_host }}:{{ logstash_lumberjack_port }}"], 5 | "ssl key": "/etc/ssl/private/logstash-forwarder.key", 6 | "ssl ca": "/etc/ssl/certs/logstash-forwarder.pem", 7 | "timeout": 15 8 | }, 9 | "files": [ 10 | { 11 | "paths": [ "{{ logstash_forwarder_path }}" ] 12 | } 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /roles/mongodb/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: install mongodb server 4 | apt: 5 | pkg: mongodb-server 6 | state: latest 7 | 8 | - name: start and enable mongodb 9 | service: 10 | name: mongodb 11 | state: started 12 | enabled: yes 13 | -------------------------------------------------------------------------------- /roles/oracle_jdk/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | oracle_jvm_location: "/usr/lib/jvm" 4 | oracle_jdk_download_url: http://download.oracle.com/otn-pub/java/jdk/{{ oracle_jdk_version }}/{{ oracle_jdk_archive }} 5 | -------------------------------------------------------------------------------- /roles/oracle_jdk/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - assert: 4 | that: 5 | - oracle_jdk_version is defined 6 | 7 | - name: install wget 8 | apt: name=wget state=present 9 | 10 | - name: check if JDK is already installed 11 | stat: path={{ oracle_jdk_location }}/release 12 | register: oracle_jdk_release_exist 13 | 14 | - name: check installed JDK version 15 | shell: '. {{ oracle_jdk_location }}/release && echo ${JAVA_VERSION}' 16 | register: oracle_jdk_installed_version 17 | changed_when: false 18 | when: oracle_jdk_release_exist.stat.exists 19 | 20 | - name: display info about JDK version 21 | debug: msg="JDK version {{ oracle_jdk_installed_version.stdout }}" 22 | when: oracle_jdk_release_exist.stat.exists 23 | 24 | - name: download JDK archive 25 | command: > 26 | wget {{ oracle_jdk_download_url }} 27 | --no-check-certificate --no-cookies -P /tmp 28 | --header "Cookie: oraclelicense=accept-securebackup-cookie" 29 | creates=/tmp/{{ oracle_jdk_archive }} 30 | when: not oracle_jdk_release_exist.stat.exists 31 | 32 | - name: create directory which contains JDK 33 | file: > 34 | path={{ oracle_jdk_location }} 35 | state=directory 36 | when: not oracle_jdk_release_exist.stat.exists 37 | 38 | - name: extract JDK archive 39 | command: > 40 | tar --no-same-owner --strip-components=1 -C {{ oracle_jdk_location }} 41 | -xzf /tmp/{{ oracle_jdk_archive }} 42 | when: not oracle_jdk_release_exist.stat.exists 43 | 44 | - name: set selected version as default 45 | file: > 46 | state=link 47 | src={{ oracle_jdk_location }} 48 | dest={{ oracle_jdk_default_link }} 49 | when: oracle_jdk_not_default is not defined 50 | 51 | - name: create java alternatives links 52 | alternatives: > 53 | name={{ item }} 54 | link=/usr/bin/{{ item }} 55 | path={{ oracle_jdk_location }}/bin/{{ item }} 56 | with_items: oracle_jdk_tools 57 | when: oracle_jdk_not_default is not defined 58 | 59 | - name: create java alternatives links (jre) 60 | alternatives: > 61 | name={{ item }} 62 | link=/usr/bin/{{ item }} 63 | path={{ oracle_jdk_location }}/jre/bin/{{ item }} 64 | with_items: oracle_jdk_jre_tools 65 | when: oracle_jdk_not_default is not defined 66 | 67 | -------------------------------------------------------------------------------- /roles/oracle_jdk/vars/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | oracle_jvm_location: "/usr/lib/jvm" 4 | 5 | oracle_jdk_arch: 6 | x86_64: x64 7 | i386: i586 8 | 9 | oracle_jdk_location: "{{ oracle_jvm_location }}/java-{{ oracle_jdk_version[0] }}-oracle-{{ oracle_jdk_version }}" 10 | oracle_jdk_archive: "jdk-{{ oracle_jdk_version.split('-')[0] }}-linux-{{ oracle_jdk_arch[ansible_architecture] }}.tar.gz" 11 | oracle_jdk_default_link: "{{ oracle_jvm_location }}/java-{{ oracle_jdk_version[0] }}-oracle" 12 | 13 | oracle_jdk_tools: 14 | - appletviewer 15 | - extcheck 16 | - idlj 17 | - jar 18 | - jarsigner 19 | - javac 20 | - javadoc 21 | - javah 22 | - javap 23 | - jconsole 24 | - jdb 25 | - jhat 26 | - jinfo 27 | - jmap 28 | - jmc 29 | - jps 30 | - jrunscript 31 | - jsadebugd 32 | - jstack 33 | - jstat 34 | - jstatd 35 | - native2ascii 36 | - rmic 37 | - schemagen 38 | - serialver 39 | - wsgen 40 | - wsimport 41 | - xjc 42 | 43 | oracle_jdk_jre_tools: 44 | - java 45 | - keytool 46 | - pack200 47 | - rmid 48 | - rmiregistry 49 | - unpack200 50 | - orbd 51 | - servertool 52 | - tnameserv 53 | -------------------------------------------------------------------------------- /roles/rundeck/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | rundeck_version: 2.6.0-1-GA 4 | rundeck_host: rundeck.example.com 5 | rundeck_port: 4440 6 | rundeck_datasource: "jdbc:h2:file:/var/lib/rundeck/data/rundeckdb" 7 | rundeck_url: "http://{{ rundeck_host }}:{{ rundeck_port }}" 8 | rundeck_basedir: /var/lib/rundeck 9 | rundeck_projects_dir: /var/rundeck/projects 10 | 11 | rundeck_cli_user: admin 12 | rundeck_cli_pass: admin 13 | 14 | rundeck_projects: 15 | - name: "deploy" 16 | ssh_keypath: "{{ rundeck_basedir }}/.ssh/id_rsa" 17 | definition: 18 | resources: 19 | server: 20 | tags: '' 21 | osFamily: unix 22 | username: root 23 | osArch: amd64 24 | description: Some server 25 | nodename: "some.machine.example.com" 26 | hostname: "some.machine.example.com" 27 | osName: Linux 28 | 29 | -------------------------------------------------------------------------------- /roles/rundeck/files/aclpolicies/admin.aclpolicy: -------------------------------------------------------------------------------- 1 | description: Admin, all access. 2 | context: 3 | project: '.*' # all projects 4 | for: 5 | resource: 6 | - allow: '*' # allow read/create all kinds 7 | adhoc: 8 | - allow: '*' # allow read/running/killing adhoc jobs 9 | job: 10 | - allow: '*' # allow read/write/delete/run/kill of all jobs 11 | node: 12 | - allow: '*' # allow read/run for all nodes 13 | by: 14 | group: admin 15 | 16 | --- 17 | 18 | description: Admin, all access. 19 | context: 20 | application: 'rundeck' 21 | for: 22 | resource: 23 | - allow: '*' # allow create of projects 24 | project: 25 | - allow: '*' # allow view/admin of all projects 26 | storage: 27 | - allow: '*' # allow read/create/update/delete for all /keys/* storage content 28 | by: 29 | group: admin 30 | -------------------------------------------------------------------------------- /roles/rundeck/files/aclpolicies/apitoken.aclpolicy: -------------------------------------------------------------------------------- 1 | description: API project level access control 2 | context: 3 | project: '.*' # all projects 4 | for: 5 | resource: 6 | - equals: 7 | kind: job 8 | allow: [create,delete] # allow create and delete jobs 9 | - equals: 10 | kind: node 11 | allow: [read,create,update,refresh] # allow refresh node sources 12 | - equals: 13 | kind: event 14 | allow: [read,create] # allow read/create events 15 | adhoc: 16 | - allow: [read,run,kill] # allow running/killing adhoc jobs and read output 17 | job: 18 | - allow: [create,read,update,delete,run,kill] # allow create/read/write/delete/run/kill of all jobs 19 | node: 20 | - allow: [read,run] # allow read/run for all nodes 21 | by: 22 | group: api_token_group 23 | 24 | --- 25 | 26 | description: API Application level access control 27 | context: 28 | application: 'rundeck' 29 | for: 30 | resource: 31 | - equals: 32 | kind: system 33 | allow: [read] # allow read of system info 34 | project: 35 | - match: 36 | name: '.*' 37 | allow: [read] # allow view of all projects 38 | storage: 39 | - match: 40 | path: '(keys|keys/.*)' 41 | allow: '*' # allow all access to manage stored keys 42 | by: 43 | group: api_token_group 44 | -------------------------------------------------------------------------------- /roles/rundeck/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: restart rundeck 4 | service: 5 | name: rundeckd 6 | state: restarted 7 | -------------------------------------------------------------------------------- /roles/rundeck/tasks/install.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: download rundeck package 4 | get_url: 5 | url: "{{ rundeck_download_url }}" 6 | dest: /tmp 7 | 8 | - name: install java 9 | apt: 10 | name: default-jre 11 | state: present 12 | 13 | - name: install rundeck package 14 | apt: 15 | deb: "/tmp/{{ rundeck_deb_filename }}" 16 | notify: 17 | - restart rundeck 18 | 19 | - name: create /tmp/rundeck directory 20 | file: 21 | path: /tmp/rundeck 22 | state: directory 23 | owner: rundeck 24 | group: rundeck 25 | 26 | - name: configure rundeck 27 | template: 28 | src: "{{ item }}.j2" 29 | dest: "/etc/rundeck/{{ item }}" 30 | owner: rundeck 31 | group: rundeck 32 | with_items: 33 | - rundeck-config.properties 34 | - framework.properties 35 | - jaas-loginmodule.conf 36 | - realm.properties 37 | - profile 38 | - log4j.properties 39 | - project.properties 40 | notify: 41 | - restart rundeck 42 | 43 | - name: ensure that ~rundeck/.ssh directory exists 44 | file: 45 | path: "{{ rundeck_basedir }}/.ssh" 46 | state: directory 47 | owner: rundeck 48 | group: rundeck 49 | mode: u=rwx,g=,o= 50 | 51 | - name: generate ssh key 52 | user: 53 | name: rundeck 54 | generate_ssh_key: yes 55 | ssh_key_file: "{{ rundeck_basedir }}/.ssh/id_rsa" 56 | ssh_key_type: rsa 57 | when: rundeck_ssh_private_key is not defined 58 | 59 | - name: copy ssh private key 60 | copy: 61 | src: "{{ rundeck_ssh_private_key }}" 62 | dest: "{{ rundeck_basedir }}/.ssh/id_rsa" 63 | owner: rundeck 64 | group: rundeck 65 | mode: u=rw,g=,o= 66 | when: rundeck_ssh_private_key is defined 67 | 68 | - name: configure ACL policies 69 | copy: 70 | src: "{{ item }}" 71 | dest: /etc/rundeck 72 | owner: rundeck 73 | mode: u=rw,g=r,o= 74 | with_fileglob: 75 | - aclpolicies/* 76 | notify: 77 | - restart rundeck 78 | 79 | - name: start and enable rundeck service 80 | service: 81 | name: rundeckd 82 | state: started 83 | enabled: yes 84 | -------------------------------------------------------------------------------- /roles/rundeck/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - include: install.yml 4 | - include: projects.yml 5 | -------------------------------------------------------------------------------- /roles/rundeck/tasks/projects.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: waiting for rundeck 4 | wait_for: 5 | host: "{{ rundeck_host }}" 6 | port: "{{ rundeck_port }}" 7 | 8 | - name: create rundeck projects 9 | command: > 10 | rd-project -a create -p {{ item.name }} -v 11 | --project.ssh-keypath={{ item.ssh_keypath }} 12 | --resources.source.1.config.file={{ rundeck_projects_dir }}/{{ item.name }}/etc/resources.yml 13 | --resources.source.1.config.format=resourceyaml 14 | --resources.source.1.config.generateFileAutomatically=true 15 | --resources.source.1.config.includeServerNode=false 16 | --resources.source.1.config.requireFileExists=false 17 | register: command_result 18 | failed_when: > 19 | command_result.rc == 1 and '409 Conflict' not in command_result.stderr 20 | changed_when: > 21 | 'Project was created' in command_result.stdout 22 | with_items: rundeck_projects 23 | 24 | - name: configure projects' resources 25 | copy: 26 | content: "{{ item.resources | to_yaml }}" 27 | dest: "{{ rundeck_projects_dir }}/{{ item.name }}/etc/resources.yml" 28 | owner: rundeck 29 | group: rundeck 30 | with_items: rundeck_projects 31 | 32 | - name: create directory for storing project definitions 33 | file: 34 | path: "{{ rundeck_basedir }}/.ansible_managed_projects" 35 | state: directory 36 | owner: rundeck 37 | group: rundeck 38 | 39 | - name: copy project definition to server 40 | copy: 41 | content: "{{ item.definition | to_yaml }}" 42 | dest: "{{ rundeck_basedir }}/.ansible_managed_projects/{{ item.name }}.yml" 43 | owner: rundeck 44 | group: rundeck 45 | register: copy_results 46 | with_items: rundeck_projects 47 | 48 | - name: update project definition 49 | command: > 50 | rd-jobs load -v -r -f {{ item.0.name }}.yml -F yaml -p {{ item.0.name }} -d update 51 | args: 52 | chdir: "{{ rundeck_basedir }}/.ansible_managed_projects" 53 | when: rundeck_force_project_update is defined or item.1.changed 54 | with_together: 55 | - rundeck_projects 56 | - copy_results.results 57 | 58 | -------------------------------------------------------------------------------- /roles/rundeck/templates/framework.properties.j2: -------------------------------------------------------------------------------- 1 | # framework.properties - 2 | # 3 | 4 | # ---------------------------------------------------------------- 5 | # Rundeck server connection information 6 | # ---------------------------------------------------------------- 7 | 8 | framework.server.name = localhost 9 | framework.server.hostname = localhost 10 | framework.server.port = 4440 11 | framework.server.url = http://localhost:4440 12 | # Username/password used by CLI tools. 13 | framework.server.username = {{ rundeck_cli_user }} 14 | framework.server.password = {{ rundeck_cli_pass }} 15 | 16 | # ---------------------------------------------------------------- 17 | # Installation locations 18 | # ---------------------------------------------------------------- 19 | 20 | rdeck.base={{ rundeck_basedir }} 21 | 22 | framework.projects.dir=/var/rundeck/projects 23 | framework.etc.dir=/etc/rundeck 24 | framework.var.dir=/var/lib/rundeck/var 25 | framework.tmp.dir=/var/lib/rundeck/var/tmp 26 | framework.logs.dir=/var/lib/rundeck/logs 27 | framework.libext.dir=/var/lib/rundeck/libext 28 | 29 | # ---------------------------------------------------------------- 30 | # SSH defaults for node executor and file copier 31 | # ---------------------------------------------------------------- 32 | 33 | framework.ssh.keypath = /var/lib/rundeck/.ssh/id_rsa 34 | framework.ssh.user = rundeck 35 | 36 | # ssh connection timeout after a specified number of milliseconds. 37 | # "0" value means wait forever. 38 | framework.ssh.timeout = 0 39 | 40 | -------------------------------------------------------------------------------- /roles/rundeck/templates/jaas-loginmodule.conf.j2: -------------------------------------------------------------------------------- 1 | RDpropertyfilelogin { 2 | 3 | org.eclipse.jetty.plus.jaas.spi.PropertyFileLoginModule required 4 | debug="true" 5 | file="/etc/rundeck/realm.properties"; 6 | 7 | }; 8 | -------------------------------------------------------------------------------- /roles/rundeck/templates/log4j.properties.j2: -------------------------------------------------------------------------------- 1 | #################################################################################################### 2 | # 3 | # Log Levels 4 | # 5 | #################################################################################################### 6 | 7 | # Enable logging for everything. Rarely useful 8 | log4j.rootLogger=warn, stdout, server-logger 9 | 10 | log4j.com.dtolabs.rundeck.core=INFO, cmd-logger 11 | 12 | #log4j.logger.org.codehaus.groovy.grails.plugins.quartz=debug,stdout 13 | #log4j.additivity.org.codehaus.groovy.grails.plugins.quartz=false 14 | 15 | # Enable audit logging 16 | log4j.logger.com.dtolabs.rundeck.core.authorization=info, audit 17 | log4j.additivity.com.dtolabs.rundeck.core.authorization=false 18 | 19 | # Enable options remote URL logging 20 | log4j.logger.com.dtolabs.rundeck.remoteservice.http.options=INFO, options 21 | log4j.additivity.com.dtolabs.rundeck.remoteservice.http.options=false 22 | 23 | # Enable Job changes logging 24 | log4j.logger.com.dtolabs.rundeck.data.jobs.changes=INFO, jobchanges 25 | log4j.additivity.com.dtolabs.rundeck.data.jobs.changes=false 26 | 27 | # Enable Execution event logging 28 | log4j.logger.org.rundeck.execution.status=INFO, execevents 29 | log4j.additivity.org.rundeck.execution.status=false 30 | 31 | # Enable API request logging 32 | log4j.logger.org.rundeck.api.requests=INFO,apirequests 33 | log4j.additivity.org.rundeck.api.requests=false 34 | 35 | # Enable Web access logging 36 | log4j.logger.org.rundeck.web.requests=INFO,access 37 | log4j.additivity.org.rundeck.web.requests=false 38 | 39 | # Enable Storage logging 40 | log4j.logger.org.rundeck.storage.events=INFO,storage 41 | log4j.additivity.org.rundeck.storage.events=false 42 | 43 | # Enable this logger to log Hibernate output 44 | # handy to see its database interaction activity 45 | #log4j.logger.org.hibernate=debug,stdout 46 | #log4j.additivity.org.hibernate=false 47 | 48 | # Enable this logger to see what Spring does, occasionally useful 49 | #log4j.logger.org.springframework=info,stdout 50 | #log4j.additivity.org.springframework=false 51 | 52 | # This logger covers all of Grails' internals 53 | # Enable to see whats going on underneath. 54 | log4j.logger.org.codehaus.groovy.grails=warn,stdout, server-logger 55 | log4j.additivity.org.codehaus.groovy.grails=false 56 | 57 | # This logger is useful if you just want to see what Grails 58 | # configures with Spring at runtime. Setting to debug will show 59 | # each bean that is configured 60 | log4j.logger.org.codehaus.groovy.grails.commons.spring=warn,stdout, server-logger 61 | log4j.additivity.org.codehaus.groovy.grails.commons.spring=false 62 | 63 | # Interesting Logger to see what some of the Grails factory beans are doing 64 | log4j.logger.org.codehaus.groovy.grails.beans.factory=warn,stdout, server-logger 65 | log4j.additivity.org.codehaus.groovy.grails.beans.factory=false 66 | 67 | # This logger is for Grails' public APIs within the grails. package 68 | log4j.logger.grails=info,stdout, server-logger 69 | log4j.additivity.grails=false 70 | 71 | 72 | #################################################################################################### 73 | # 74 | # Appender Configuration (unlikely a change needs to be made, unless you have unique logging reqs.) 75 | # 76 | #################################################################################################### 77 | 78 | # 79 | # stdout - ConsoleAppender 80 | # 81 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender 82 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 83 | log4j.appender.stdout.layout.ConversionPattern=%-5p %c{1}: %m%n 84 | 85 | # 86 | # cmd-logger - DailyRollingFileAppender 87 | # 88 | # Output of the RunDeck command line utilities 89 | # 90 | log4j.appender.cmd-logger=org.apache.log4j.DailyRollingFileAppender 91 | log4j.appender.cmd-logger.file=/var/log/rundeck/command.log 92 | log4j.appender.cmd-logger.datePattern='.'yyyy-MM-dd 93 | log4j.appender.cmd-logger.append=true 94 | log4j.appender.cmd-logger.layout=org.apache.log4j.PatternLayout 95 | log4j.appender.cmd-logger.layout.ConversionPattern=%d{ISO8601} [%t] %-5p %c - %m%n 96 | 97 | # 98 | # server-logger - DailyRollingFileAppender 99 | # 100 | # Captures all output from the rundeckd server. 101 | # 102 | log4j.appender.server-logger=org.apache.log4j.DailyRollingFileAppender 103 | log4j.appender.server-logger.file=/var/log/rundeck/rundeck.log 104 | log4j.appender.server-logger.datePattern='.'yyyy-MM-dd 105 | log4j.appender.server-logger.append=true 106 | log4j.appender.server-logger.layout=org.apache.log4j.PatternLayout 107 | log4j.appender.server-logger.layout.ConversionPattern=%d{ISO8601} [%t] %-5p %c - %m%n 108 | 109 | # 110 | # audit 111 | # 112 | # Captures all audit events. 113 | # 114 | log4j.appender.audit=org.apache.log4j.DailyRollingFileAppender 115 | log4j.appender.audit.file=/var/log/rundeck/rundeck.audit.log 116 | log4j.appender.audit.append=true 117 | log4j.appender.audit.layout=org.apache.log4j.PatternLayout 118 | log4j.appender.audit.layout.ConversionPattern=%d{ISO8601} - %m%n 119 | 120 | # 121 | # options log 122 | # 123 | # Logs remote HTTP requests for Options JSON data 124 | # 125 | log4j.appender.options=org.apache.log4j.DailyRollingFileAppender 126 | log4j.appender.options.file=/var/log/rundeck/rundeck.options.log 127 | log4j.appender.options.append=true 128 | log4j.appender.options.layout=org.apache.log4j.PatternLayout 129 | log4j.appender.options.layout.ConversionPattern=[%d{ISO8601}] %X{httpStatusCode} %X{contentLength}B %X{durationTime}ms %X{lastModifiedDateTime} [%X{jobName}] %X{url} %X{contentSHA1}%n 130 | 131 | # 132 | # storage log 133 | # 134 | # Logs events for Rundeck storage layer 135 | # 136 | log4j.appender.storage=org.apache.log4j.DailyRollingFileAppender 137 | log4j.appender.storage.file=/var/log/rundeck/rundeck.storage.log 138 | log4j.appender.storage.append=true 139 | log4j.appender.storage.layout=org.apache.log4j.PatternLayout 140 | log4j.appender.storage.layout.ConversionPattern=[%d{ISO8601}] %X{action} %X{type} %X{path} %X{status} %X{metadata}%n 141 | 142 | # 143 | # job changes log 144 | # 145 | # Logs all Job definition changes 146 | # 147 | log4j.appender.jobchanges=org.apache.log4j.DailyRollingFileAppender 148 | log4j.appender.jobchanges.file=/var/log/rundeck/rundeck.jobs.log 149 | log4j.appender.jobchanges.append=true 150 | log4j.appender.jobchanges.layout=org.apache.log4j.PatternLayout 151 | log4j.appender.jobchanges.layout.ConversionPattern=[%d{ISO8601}] %X{user} %X{change} [%X{id}] %X{project} "%X{groupPath}/%X{jobName}" (%X{method})%n 152 | 153 | # 154 | # executions log 155 | # 156 | # Logs all execution events (start,finish,delete) 157 | # 158 | log4j.appender.execevents=org.apache.log4j.DailyRollingFileAppender 159 | log4j.appender.execevents.file=/var/log/rundeck/rundeck.executions.log 160 | log4j.appender.execevents.append=true 161 | log4j.appender.execevents.layout=org.apache.log4j.PatternLayout 162 | log4j.appender.execevents.layout.ConversionPattern=[%d{ISO8601}] %X{eventUser} %X{event} [%X{id}:%X{state}] %X{project} %X{user}/%X{abortedby} "%X{groupPath}/%X{jobName}"[%X{uuid}]%n 163 | 164 | # 165 | # api request log 166 | # 167 | # Logs all API requests 168 | # 169 | log4j.appender.apirequests=org.apache.log4j.DailyRollingFileAppender 170 | log4j.appender.apirequests.file=/var/log/rundeck/rundeck.api.log 171 | log4j.appender.apirequests.append=true 172 | log4j.appender.apirequests.layout=org.apache.log4j.PatternLayout 173 | log4j.appender.apirequests.layout.ConversionPattern=[%d{ISO8601}] %X{remoteHost} %X{secure} %X{remoteUser} %X{authToken} %X{duration} %X{project} "%X{method} %X{uri}" (%X{userAgent})%n 174 | 175 | # 176 | # Web access log 177 | # 178 | # Logs all Web requests 179 | # 180 | log4j.appender.access=org.apache.log4j.DailyRollingFileAppender 181 | log4j.appender.access.file=/var/log/rundeck/rundeck.access.log 182 | log4j.appender.access.append=true 183 | log4j.appender.access.layout=org.apache.log4j.PatternLayout 184 | log4j.appender.access.layout.ConversionPattern=[%d{ISO8601}] "%X{method} %X{uri}" %X{remoteHost} %X{secure} %X{remoteUser} %X{authToken} %X{duration} %X{project} [%X{contentType}] (%X{userAgent})%n 185 | 186 | # 187 | # Disable h2database logging 188 | # workaround for issue https://github.com/rundeck/rundeck/issues/1175 189 | log4j.logger.h2database = off 190 | -------------------------------------------------------------------------------- /roles/rundeck/templates/profile.j2: -------------------------------------------------------------------------------- 1 | RDECK_BASE=/var/lib/rundeck 2 | export RDECK_BASE 3 | 4 | JAVA_CMD=java 5 | RUNDECK_TEMPDIR=/tmp/rundeck 6 | 7 | RDECK_HTTP_PORT=4440 8 | RDECK_HTTPS_PORT=4443 9 | 10 | # 11 | # If JAVA_HOME is set, then add it to home and set JAVA_CMD to use the version specified in that 12 | # path. JAVA_HOME can be set in the rundeck profile. Or set in this file. 13 | #JAVA_HOME= 14 | 15 | if [ ! -z $JAVA_HOME ]; then 16 | PATH=$PATH:$JAVA_HOME/bin 17 | export PATH 18 | JAVA_CMD=$JAVA_HOME/bin/java 19 | fi 20 | 21 | 22 | 23 | export CLI_CP=$(find /var/lib/rundeck/cli -name \*.jar -printf %p:) 24 | export BOOTSTRAP_CP=$(find /var/lib/rundeck/bootstrap -name \*.jar -printf %p:) 25 | export RDECK_JVM="-Djava.security.auth.login.config=/etc/rundeck/jaas-loginmodule.conf \ 26 | -Dloginmodule.name=RDpropertyfilelogin \ 27 | -Drdeck.config=/etc/rundeck \ 28 | -Drdeck.base=/var/lib/rundeck \ 29 | -Drundeck.server.configDir=/etc/rundeck \ 30 | -Dserver.datastore.path=/var/lib/rundeck/data \ 31 | -Drundeck.server.serverDir=/var/lib/rundeck \ 32 | -Drdeck.projects=/var/rundeck/projects \ 33 | -Drdeck.runlogs=/var/lib/rundeck/logs \ 34 | -Drundeck.config.location=/etc/rundeck/rundeck-config.properties \ 35 | -Djava.io.tmpdir=$RUNDECK_TEMPDIR" 36 | # 37 | # Set min/max heap size 38 | # 39 | RDECK_JVM="$RDECK_JVM -Xmx1024m -Xms256m -XX:MaxPermSize=256m -server" 40 | # 41 | # SSL Configuration - Uncomment the following to enable. Check SSL.properties for details. 42 | # 43 | #export RDECK_JVM="$RDECK_JVM -Drundeck.ssl.config=/etc/rundeck/ssl/ssl.properties -Dserver.https.port=${RDECK_HTTPS_PORT}" 44 | 45 | export RDECK_SSL_OPTS="-Djavax.net.ssl.trustStore=/etc/rundeck/ssl/truststore -Djavax.net.ssl.trustStoreType=jks -Djava.protocol.handler.pkgs=com.sun.net.ssl.internal.www.protocol" 46 | 47 | if test -t 0 -a -z "$RUNDECK_CLI_TERSE" 48 | then 49 | RUNDECK_CLI_TERSE=true 50 | export RUNDECK_CLI_TERSE 51 | fi 52 | 53 | if test -n "$JRE_HOME" 54 | then 55 | unset JRE_HOME 56 | fi 57 | 58 | umask 002 59 | -------------------------------------------------------------------------------- /roles/rundeck/templates/project.properties.j2: -------------------------------------------------------------------------------- 1 | # project.properties 2 | # 3 | # $Id: project.properties.template 2126 2010-08-17 21:06:08Z ahonor $ 4 | # 5 | 6 | # 7 | # The base directory for this project's instances 8 | # 9 | project.dir = /var/rundeck/projects/${project.name} 10 | # 11 | # The base directory of project specific configuration files 12 | # 13 | project.etc.dir = /var/rundeck/projects/${project.name}/etc 14 | 15 | # 16 | # The resources registration file 17 | # 18 | project.resources.file = /var/rundeck/projects/${project.name}/etc/resources.xml 19 | 20 | # 21 | # The project description 22 | # 23 | project.description = 24 | # 25 | # The organization 26 | # 27 | project.organization = 28 | -------------------------------------------------------------------------------- /roles/rundeck/templates/realm.properties.j2: -------------------------------------------------------------------------------- 1 | 2 | # TODO: store passwords in ansible-vault? 3 | 4 | # 5 | # This file defines users passwords and roles for a HashUserRealm 6 | # 7 | # The format is 8 | # : [, ...] 9 | # 10 | # Passwords may be clear text, obfuscated or checksummed. The class 11 | # org.mortbay.util.Password should be used to generate obfuscated 12 | # passwords or password checksums 13 | # 14 | # If DIGEST Authentication is used, the password must be in a recoverable 15 | # format, either plain text or OBF:. 16 | # 17 | #jetty: MD5:164c88b302622e17050af52c89945d44,user 18 | #admin: CRYPT:ad1ks..kc.1Ug,server-administrator,content-administrator,admin 19 | #other: OBF:1xmk1w261u9r1w1c1xmq 20 | #plain: plain 21 | #user: password 22 | # This entry is for digest auth. The credential is a MD5 hash of username:realmname:password 23 | #digest: MD5:6e120743ad67abfbc385bc2bb754e297 24 | 25 | # 26 | # This sets the default user accounts for the Rundeck app 27 | # 28 | admin:admin,user,admin,architect,deploy,build 29 | #@jetty.user.deploy.name@:@jetty.user.deploy.password@,user,deploy 30 | #@jetty.user.build.name@:@jetty.user.build.password@,user,build 31 | -------------------------------------------------------------------------------- /roles/rundeck/templates/rundeck-config.properties.j2: -------------------------------------------------------------------------------- 1 | loglevel.default=INFO 2 | rdeck.base={{ rundeck_basedir }} 3 | rss.enabled=false 4 | grails.serverURL={{ rundeck_url }} 5 | dataSource.dbCreate = update 6 | dataSource.url = {{ rundeck_datasource }} 7 | -------------------------------------------------------------------------------- /roles/rundeck/vars/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | rundeck_deb_filename: rundeck-{{ rundeck_version }}.deb 4 | rundeck_download_url: http://dl.bintray.com/rundeck/rundeck-deb/{{ rundeck_deb_filename }} 5 | -------------------------------------------------------------------------------- /roles/seyren/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | seyren_user: seyren 4 | seyren_group: seyren 5 | 6 | seyren_download_url: "https://github.com/scobal/seyren/releases/download/{{ seyren_version }}/seyren-{{ seyren_version }}.jar" 7 | seyren_dir: /srv/seyren 8 | seyren_version: 1.3.0 9 | 10 | seyren_graphite_url: http://graphite.example.com:80 11 | seyren_port: 8080 12 | seyren_url: http://localhost:8080 13 | -------------------------------------------------------------------------------- /roles/seyren/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: restart seyren 4 | service: 5 | name: seyren 6 | state: restarted 7 | -------------------------------------------------------------------------------- /roles/seyren/meta/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | dependencies: 4 | - { role: mongodb } 5 | - { role: oracle_jdk, oracle_jdk_version: '8u45-b14' } 6 | -------------------------------------------------------------------------------- /roles/seyren/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: create seyren service group 4 | group: 5 | name: "{{ seyren_group }}" 6 | system: yes 7 | state: present 8 | 9 | - name: create seyren service user 10 | user: 11 | name: "{{ seyren_user }}" 12 | group: "{{ seyren_group }}" 13 | shell: /bin/false 14 | system: yes 15 | home: "{{ seyren_dir }}" 16 | 17 | - name: create seyren directories 18 | file: 19 | path: "{{ seyren_dir }}" 20 | state: directory 21 | owner: "{{ seyren_user }}" 22 | group: "{{ seyren_group }}" 23 | 24 | - name: download jar file 25 | get_url: 26 | url: "{{ seyren_download_url }}" 27 | dest: "{{ seyren_dir }}/seyren-{{ seyren_version }}.jar" 28 | owner: "{{ seyren_user }}" 29 | group: "{{ seyren_group }}" 30 | notify: 31 | - restart seyren 32 | 33 | - name: create service configuration 34 | template: 35 | src: seyren.service.j2 36 | dest: /etc/systemd/system/seyren.service 37 | register: 38 | template_result 39 | notify: 40 | - restart seyren 41 | 42 | - name: reload systemd manager configuration 43 | command: 44 | systemctl daemon-reload 45 | when: 46 | template_result.changed 47 | 48 | - name: start and enable service 49 | service: 50 | name: seyren 51 | state: started 52 | enabled: yes 53 | -------------------------------------------------------------------------------- /roles/seyren/templates/seyren.service.j2: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Seyren 3 | After=network.target 4 | 5 | [Service] 6 | User={{ seyren_user }} 7 | Group={{ seyren_group }} 8 | WorkingDirectory={{ seyren_dir }} 9 | Environment=GRAPHITE_URL={{ seyren_graphite_url }} 10 | Environment=SEYREN_URL={{ seyren_url }} 11 | ExecStart=/usr/bin/java -jar {{ seyren_dir }}/seyren-{{ seyren_version }}.jar -httpPort={{ seyren_port }} 12 | ExecStop=/bin/kill -s TERM $MAINPID 13 | TimeoutSec=300 14 | 15 | [Install] 16 | WantedBy=multi-user.target 17 | -------------------------------------------------------------------------------- /roles/sonatype-nexus/README.md: -------------------------------------------------------------------------------- 1 | Code based on sonatype-nexux role by Matt Willsher. 2 | -------------------------------------------------------------------------------- /roles/sonatype-nexus/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | sonatype_nexus_port: 8080 3 | sonatype_nexus_version: latest 4 | sonatype_nexus_application_port: 8081 5 | sonatype_nexus_application_host: 0.0.0.0 6 | sonatype_nexus_work_dir: /var/lib/sonatype-nexus 7 | sonatype_nexus_pid_dir: "{{ sonatype_nexus_work_dir }}" 8 | sonatype_nexus_webapp_context_path: /nexus 9 | sonatype_nexus_nginx: off 10 | sonatype_nexus_nginx_fqdn: nexus 11 | sonatype_nexus_nginx_default_site: no 12 | sonatype_nexus_nginx_ssl: no 13 | sonatype_nexus_nginx_ssl_cert_file: sonatype_nexus.crt 14 | sonatype_nexus_nginx_ssl_key_file: sonatype_nexus.key 15 | sonatype_nexus_openjdk: yes 16 | sonatype_nexus_user: nexus 17 | -------------------------------------------------------------------------------- /roles/sonatype-nexus/files/nexus.init: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | ### BEGIN INIT INFO 4 | # Provides: nexus 5 | # Required-Start: $network 6 | # Required-Stop: $network 7 | # Default-Start: 2 3 4 5 8 | # Default-Stop: 9 | # Short-Description: Start Nexus OSS 10 | ### END INIT INFO 11 | 12 | 13 | # 14 | # Copyright (c) 1999, 2006 Tanuki Software Inc. 15 | # 16 | # Java Service Wrapper sh script. Suitable for starting and stopping 17 | # wrapped Java applications on UNIX platforms. 18 | # 19 | 20 | #----------------------------------------------------------------------------- 21 | # These settings can be modified to fit the needs of your application 22 | 23 | # Set this to the root of the Nexus installation 24 | NEXUS_HOME="/opt/sonatype-nexus" 25 | 26 | # If specified, the Wrapper will be run as the specified user. 27 | 28 | # IMPORTANT - Make sure that the user has the required privileges to write into the Nexus installation directory. 29 | 30 | # NOTE - This will set the user which is used to run the Wrapper as well as 31 | # the JVM and is not useful in situations where a privileged resource or 32 | # port needs to be allocated prior to the user being changed. 33 | #RUN_AS_USER= 34 | RUN_AS_USER="nexus" 35 | 36 | # Application 37 | APP_NAME="nexus" 38 | APP_LONG_NAME="Nexus OSS" 39 | 40 | # Priority at which to run the wrapper. See "man nice" for valid priorities. 41 | # nice is only used if a priority is specified. 42 | PRIORITY= 43 | 44 | # Location of the pid file. 45 | #PIDDIR="." 46 | PIDDIR="/var/lib/sonatype-nexus" 47 | 48 | # If uncommented, causes the Wrapper to be shutdown using an anchor file. 49 | # When launched with the 'start' command, it will also ignore all INT and 50 | # TERM signals. 51 | #IGNORE_SIGNALS=true 52 | 53 | # The following two lines are used by the chkconfig command. Change as is 54 | # appropriate for your application. They should remain commented. 55 | # chkconfig: 2345 20 80 56 | # description: Test Wrapper Sample Application 57 | 58 | # Do not modify anything beyond this point 59 | #----------------------------------------------------------------------------- 60 | 61 | # Get the fully qualified path to the script 62 | case $0 in 63 | /*) 64 | SCRIPT="$0" 65 | ;; 66 | *) 67 | PWD=`pwd` 68 | SCRIPT="$PWD/$0" 69 | ;; 70 | esac 71 | 72 | # Resolve the true real path without any sym links. 73 | CHANGED=true 74 | while [ "X$CHANGED" != "X" ] 75 | do 76 | # Change spaces to ":" so the tokens can be parsed. 77 | SAFESCRIPT=`echo $SCRIPT | sed -e 's; ;:;g'` 78 | # Get the real path to this script, resolving any symbolic links 79 | TOKENS=`echo $SAFESCRIPT | sed -e 's;/; ;g'` 80 | REALPATH= 81 | for C in $TOKENS; do 82 | # Change any ":" in the token back to a space. 83 | C=`echo $C | sed -e 's;:; ;g'` 84 | REALPATH="$REALPATH/$C" 85 | # If REALPATH is a sym link, resolve it. Loop for nested links. 86 | while [ -h "$REALPATH" ] ; do 87 | LS="`ls -ld "$REALPATH"`" 88 | LINK="`expr "$LS" : '.*-> \(.*\)$'`" 89 | if expr "$LINK" : '/.*' > /dev/null; then 90 | # LINK is absolute. 91 | REALPATH="$LINK" 92 | else 93 | # LINK is relative. 94 | REALPATH="`dirname "$REALPATH"`""/$LINK" 95 | fi 96 | done 97 | done 98 | 99 | if [ "$REALPATH" = "$SCRIPT" ] 100 | then 101 | CHANGED="" 102 | else 103 | SCRIPT="$REALPATH" 104 | fi 105 | done 106 | 107 | # Change the current directory to the location of the script 108 | cd "`dirname "$REALPATH"`" 109 | REALDIR=`pwd` 110 | 111 | # Resolve the location of the 'ps' command 112 | PSEXE="/usr/bin/ps" 113 | if [ ! -x "$PSEXE" ] 114 | then 115 | PSEXE="/bin/ps" 116 | if [ ! -x "$PSEXE" ] 117 | then 118 | echo "Unable to locate 'ps'." 119 | echo "Please report this message along with the location of the command on your system." 120 | exit 1 121 | fi 122 | fi 123 | 124 | # Resolve the os 125 | DIST_OS=`uname -s | tr [:upper:] [:lower:] | tr -d [:blank:]` 126 | case "$DIST_OS" in 127 | 'sunos') 128 | DIST_OS="solaris" 129 | PSEXE="/usr/ucb/ps" 130 | ;; 131 | 'hp-ux' | 'hp-ux64') 132 | DIST_OS="hpux" 133 | ;; 134 | 'darwin') 135 | DIST_OS="macosx" 136 | ;; 137 | 'unix_sv') 138 | DIST_OS="unixware" 139 | ;; 140 | esac 141 | 142 | # Resolve the architecture 143 | DIST_ARCH=`uname -p | tr [:upper:] [:lower:] | tr -d [:blank:]` 144 | DIST_BITS=32 145 | if [ "$DIST_ARCH" = "unknown" ] 146 | then 147 | DIST_ARCH=`uname -m | tr [:upper:] [:lower:] | tr -d [:blank:]` 148 | fi 149 | case "$DIST_ARCH" in 150 | 'athlon' | 'ia32' | 'i386' | 'i486' | 'i586' | 'i686') 151 | DIST_ARCH="x86" 152 | ;; 153 | 'amd64' | 'x86_64' | 'ia64') 154 | DIST_ARCH="x86" 155 | DIST_BITS=64 156 | ;; 157 | 'ip27') 158 | DIST_ARCH="mips" 159 | ;; 160 | 'power' | 'powerpc' | 'power_pc') 161 | DIST_ARCH="ppc" 162 | ;; 163 | 'ppc64') 164 | DIST_ARCH="ppc" 165 | DIST_BITS=64 166 | ;; 167 | 'pa_risc' | 'pa-risc') 168 | DIST_ARCH="parisc" 169 | ;; 170 | 'sun4u' | 'sparcv9') 171 | DIST_ARCH="sparc" 172 | ;; 173 | '9000/800') 174 | DIST_ARCH="parisc" 175 | ;; 176 | esac 177 | 178 | # Extra architecture detection 179 | case "$DIST_OS" in 180 | 'macosx') 181 | if [ `sysctl hw.cpu64bit_capable | awk '{ print $2 }'` = '1' ]; then 182 | DIST_BITS=64 183 | fi 184 | DIST_ARCH='universal' 185 | ;; 186 | 'aix') 187 | DIST_BITS=`getconf KERNEL_BITMODE` 188 | ;; 189 | esac 190 | 191 | outputFile() { 192 | if [ -f "$1" ] 193 | then 194 | echo " $1 (Found but not executable.)"; 195 | else 196 | echo " $1" 197 | fi 198 | } 199 | 200 | # Test if NEXUS_HOME is relative (does not start with /). If relative it should be relative to this script location 201 | FIRST_CHAR=`echo $NEXUS_HOME | cut -c1,1` 202 | if [ "$FIRST_CHAR" != "/" ] 203 | then 204 | NEXUS_HOME=$REALDIR/$NEXUS_HOME 205 | fi 206 | 207 | # Default PIDDIR to os/arch/bits directory 208 | if [ "X$PIDDIR" = "X" ] 209 | then 210 | PIDDIR="bin/jsw/$DIST_OS-$DIST_ARCH-$DIST_BITS" 211 | fi 212 | 213 | # If the PIDDIR is relative, set its value relative to the full NEXUS_HOME to avoid problems if 214 | # the working directory is later changed. 215 | FIRST_CHAR=`echo $PIDDIR | cut -c1,1` 216 | if [ "$FIRST_CHAR" != "/" ] 217 | then 218 | PIDDIR=$NEXUS_HOME/$PIDDIR 219 | fi 220 | 221 | # Process ID 222 | ANCHORFILE="$PIDDIR/$APP_NAME.anchor" 223 | PIDFILE="$PIDDIR/$APP_NAME.pid" 224 | LOCKDIR="/var/lock/subsys" 225 | LOCKFILE="$LOCKDIR/$APP_NAME" 226 | pid="" 227 | 228 | WRAPPER_CMD="$NEXUS_HOME/bin/jsw/$DIST_OS-$DIST_ARCH-$DIST_BITS/wrapper" 229 | if [ ! -x "$WRAPPER_CMD" ]; then 230 | echo "Missing platform binary: $WRAPPER_CMD" 231 | exit 1 232 | fi 233 | 234 | WRAPPER_CONF="$NEXUS_HOME/bin/jsw/conf/wrapper.conf" 235 | 236 | # Build the nice clause 237 | if [ "X$PRIORITY" = "X" ] 238 | then 239 | CMDNICE="" 240 | else 241 | CMDNICE="nice -$PRIORITY" 242 | fi 243 | 244 | # Build the anchor file clause. 245 | if [ "X$IGNORE_SIGNALS" = "X" ] 246 | then 247 | ANCHORPROP= 248 | IGNOREPROP= 249 | else 250 | ANCHORPROP=wrapper.anchorfile=\"$ANCHORFILE\" 251 | IGNOREPROP=wrapper.ignore_signals=TRUE 252 | fi 253 | 254 | # Build the lock file clause. Only create a lock file if the lock directory exists on this platform. 255 | LOCKPROP= 256 | if [ -d $LOCKDIR ] 257 | then 258 | if [ -w $LOCKDIR ] 259 | then 260 | LOCKPROP=wrapper.lockfile=\"$LOCKFILE\" 261 | fi 262 | fi 263 | 264 | checkUser() { 265 | # $1 touchLock flag 266 | # $2 command 267 | 268 | # Resolve the location of the 'id' command 269 | IDEXE="/usr/xpg4/bin/id" 270 | if [ ! -x "$IDEXE" ] 271 | then 272 | IDEXE="/usr/bin/id" 273 | if [ ! -x "$IDEXE" ] 274 | then 275 | echo "Unable to locate 'id'." 276 | echo "Please report this message along with the location of the command on your system." 277 | exit 1 278 | fi 279 | fi 280 | 281 | # Check the configured user. If necessary rerun this script as the desired user. 282 | if [ "X$RUN_AS_USER" != "X" ] 283 | then 284 | if [ "`$IDEXE -u -n`" != "$RUN_AS_USER" ] 285 | then 286 | # If LOCKPROP and $RUN_AS_USER are defined then the new user will most likely not be 287 | # able to create the lock file. The Wrapper will be able to update this file once it 288 | # is created but will not be able to delete it on shutdown. If $2 is defined then 289 | # the lock file should be created for the current command 290 | if [ "X$LOCKPROP" != "X" ] 291 | then 292 | if [ "X$1" != "X" ] 293 | then 294 | # Resolve the primary group 295 | RUN_AS_GROUP=`groups $RUN_AS_USER | awk '{print $3}' | tail -1` 296 | if [ "X$RUN_AS_GROUP" = "X" ] 297 | then 298 | RUN_AS_GROUP=$RUN_AS_USER 299 | fi 300 | touch $LOCKFILE 301 | chown $RUN_AS_USER:$RUN_AS_GROUP $LOCKFILE 302 | fi 303 | fi 304 | 305 | # Still want to change users, recurse. This means that the user will only be 306 | # prompted for a password once. Variables shifted by 1 307 | su - $RUN_AS_USER -c "\"$REALPATH\" $2" 308 | 309 | # Now that we are the original user again, we may need to clean up the lock file. 310 | if [ "X$LOCKPROP" != "X" ] 311 | then 312 | getpid 313 | if [ "X$pid" = "X" ] 314 | then 315 | # Wrapper is not running so make sure the lock file is deleted. 316 | if [ -f "$LOCKFILE" ] 317 | then 318 | rm "$LOCKFILE" 319 | fi 320 | fi 321 | fi 322 | 323 | exit 0 324 | fi 325 | fi 326 | 327 | # Check that script is not run as root 328 | LUID=`$IDEXE -u` 329 | if [ $LUID -eq 0 ] 330 | then 331 | echo "****************************************" 332 | echo "WARNING - NOT RECOMMENDED TO RUN AS ROOT" 333 | echo "****************************************" 334 | if [ ! "`$IDEXE -u -n`" = "$RUN_AS_USER" ] 335 | then 336 | echo "If you insist running as root, then set the environment variable RUN_AS_USER=root before running this script." 337 | exit 1 338 | fi 339 | fi 340 | } 341 | 342 | getpid() { 343 | if [ -f "$PIDFILE" ] 344 | then 345 | if [ -r "$PIDFILE" ] 346 | then 347 | pid=`cat "$PIDFILE"` 348 | if [ "X$pid" != "X" ] 349 | then 350 | # It is possible that 'a' process with the pid exists but that it is not the 351 | # correct process. This can happen in a number of cases, but the most 352 | # common is during system startup after an unclean shutdown. 353 | # The ps statement below looks for the specific wrapper command running as 354 | # the pid. If it is not found then the pid file is considered to be stale. 355 | case "$DIST_OS" in 356 | 'macosx') 357 | pidtest=`$PSEXE -ww -p $pid -o command | grep "wrapper.pidfile" | tail -1` 358 | ;; 359 | 'solaris') 360 | pidtest=`$PSEXE ww $pid | grep "wrapper.pidfile" | tail -1` 361 | ;; 362 | *) 363 | pidtest=`$PSEXE -p $pid -o args | grep "wrapper.pidfile" | tail -1` 364 | ;; 365 | esac 366 | if [ "X$pidtest" = "X" ] 367 | then 368 | # This is a stale pid file. 369 | rm -f "$PIDFILE" 370 | echo "Removed stale pid file: $PIDFILE" 371 | pid="" 372 | fi 373 | fi 374 | else 375 | echo "Cannot read $PIDFILE." 376 | exit 1 377 | fi 378 | fi 379 | } 380 | 381 | testpid() { 382 | if [ "$DIST_OS" = "solaris" ] 383 | then 384 | pid=`$PSEXE ww $pid | grep $pid | grep -v grep | awk '{print $1}' | tail -1` 385 | else 386 | pid=`$PSEXE -p $pid | grep $pid | grep -v grep | awk '{print $1}' | tail -1` 387 | fi 388 | if [ "X$pid" = "X" ] 389 | then 390 | # Process is gone so remove the pid file. 391 | rm -f "$PIDFILE" 392 | pid="" 393 | fi 394 | } 395 | 396 | console() { 397 | echo "Running $APP_LONG_NAME..." 398 | getpid 399 | if [ "X$pid" = "X" ] 400 | then 401 | # The string passed to eval must handles spaces in paths correctly. 402 | COMMAND_LINE="$CMDNICE \"$WRAPPER_CMD\" \"$WRAPPER_CONF\" wrapper.syslog.ident=$APP_NAME wrapper.pidfile=\"$PIDFILE\" $ANCHORPROP $LOCKPROP" 403 | eval $COMMAND_LINE 404 | else 405 | echo "$APP_LONG_NAME is already running." 406 | exit 1 407 | fi 408 | } 409 | 410 | start() { 411 | echo "Starting $APP_LONG_NAME..." 412 | getpid 413 | if [ "X$pid" = "X" ] 414 | then 415 | # The string passed to eval must handles spaces in paths correctly. 416 | COMMAND_LINE="$CMDNICE \"$WRAPPER_CMD\" \"$WRAPPER_CONF\" wrapper.syslog.ident=$APP_NAME wrapper.pidfile=\"$PIDFILE\" wrapper.daemonize=TRUE $ANCHORPROP $IGNOREPROP $LOCKPROP" 417 | eval $COMMAND_LINE 418 | else 419 | echo "$APP_LONG_NAME is already running." 420 | exit 1 421 | fi 422 | getpid 423 | if [ "X$pid" != "X" ] 424 | then 425 | echo "Started $APP_LONG_NAME." 426 | else 427 | echo "Failed to start $APP_LONG_NAME." 428 | fi 429 | } 430 | 431 | stopit() { 432 | echo "Stopping $APP_LONG_NAME..." 433 | getpid 434 | if [ "X$pid" = "X" ] 435 | then 436 | echo "$APP_LONG_NAME was not running." 437 | else 438 | if [ "X$IGNORE_SIGNALS" = "X" ] 439 | then 440 | # Running so try to stop it. 441 | kill $pid 442 | if [ $? -ne 0 ] 443 | then 444 | # An explanation for the failure should have been given 445 | echo "Unable to stop $APP_LONG_NAME." 446 | exit 1 447 | fi 448 | else 449 | rm -f "$ANCHORFILE" 450 | if [ -f "$ANCHORFILE" ] 451 | then 452 | # An explanation for the failure should have been given 453 | echo "Unable to stop $APP_LONG_NAME." 454 | exit 1 455 | fi 456 | fi 457 | 458 | # We can not predict how long it will take for the wrapper to 459 | # actually stop as it depends on settings in wrapper.conf. 460 | # Loop until it does. 461 | savepid=$pid 462 | CNT=0 463 | TOTCNT=0 464 | while [ "X$pid" != "X" ] 465 | do 466 | # Show a waiting message every 5 seconds. 467 | if [ "$CNT" -lt "5" ] 468 | then 469 | CNT=`expr $CNT + 1` 470 | else 471 | echo "Waiting for $APP_LONG_NAME to exit..." 472 | CNT=0 473 | fi 474 | TOTCNT=`expr $TOTCNT + 1` 475 | 476 | sleep 1 477 | 478 | testpid 479 | done 480 | 481 | pid=$savepid 482 | testpid 483 | if [ "X$pid" != "X" ] 484 | then 485 | echo "Failed to stop $APP_LONG_NAME." 486 | exit 1 487 | else 488 | echo "Stopped $APP_LONG_NAME." 489 | fi 490 | fi 491 | } 492 | 493 | status() { 494 | getpid 495 | if [ "X$pid" = "X" ] 496 | then 497 | echo "$APP_LONG_NAME is not running." 498 | exit 1 499 | else 500 | echo "$APP_LONG_NAME is running ($pid)." 501 | exit 0 502 | fi 503 | } 504 | 505 | dump() { 506 | echo "Dumping $APP_LONG_NAME..." 507 | getpid 508 | if [ "X$pid" = "X" ] 509 | then 510 | echo "$APP_LONG_NAME was not running." 511 | 512 | else 513 | kill -3 $pid 514 | 515 | if [ $? -ne 0 ] 516 | then 517 | echo "Failed to dump $APP_LONG_NAME." 518 | exit 1 519 | else 520 | echo "Dumped $APP_LONG_NAME." 521 | fi 522 | fi 523 | } 524 | 525 | case "$1" in 526 | 527 | 'console') 528 | checkUser touchlock $1 529 | console 530 | ;; 531 | 532 | 'start') 533 | checkUser touchlock $1 534 | start 535 | ;; 536 | 537 | 'stop') 538 | checkUser "" $1 539 | stopit 540 | ;; 541 | 542 | 'restart') 543 | checkUser touchlock $1 544 | stopit 545 | start 546 | ;; 547 | 548 | 'status') 549 | checkUser "" $1 550 | status 551 | ;; 552 | 553 | 'dump') 554 | checkUser "" $1 555 | dump 556 | ;; 557 | 558 | *) 559 | echo "Usage: $0 { console | start | stop | restart | status | dump }" 560 | exit 1 561 | ;; 562 | esac 563 | 564 | exit 0 565 | -------------------------------------------------------------------------------- /roles/sonatype-nexus/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: restart sonatype-nexus 4 | service: name=nexus state=restarted 5 | 6 | - name: restart nginx 7 | service: name=nginx state=restarted 8 | 9 | -------------------------------------------------------------------------------- /roles/sonatype-nexus/tasks/configure.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Set NEXUS_HOME 3 | lineinfile: dest={{ sonatype_nexus_root_dir }}/{{ nexus_directory.stdout }}/bin/nexus 4 | regexp='^NEXUS_HOME="' 5 | line='NEXUS_HOME="{{ sonatype_nexus_dir }}"' 6 | notify: 7 | - restart sonatype-nexus 8 | 9 | - name: Set PIDDIR 10 | lineinfile: dest={{ sonatype_nexus_root_dir }}/{{ nexus_directory.stdout }}/bin/nexus 11 | regexp='^PIDDIR="' 12 | insertafter="#PIDDIR=" 13 | line='PIDDIR="{{ sonatype_nexus_pid_dir }}"' 14 | notify: 15 | - restart sonatype-nexus 16 | 17 | - name: Set RUN_AS_USER 18 | lineinfile: dest={{ sonatype_nexus_root_dir }}/{{ nexus_directory.stdout }}/bin/nexus 19 | regexp='^RUN_AS_USER="' 20 | insertafter="#RUN_AS_USER=" 21 | line='RUN_AS_USER="{{sonatype_nexus_user}}"' 22 | notify: 23 | - restart sonatype-nexus 24 | 25 | - name: Set application-port 26 | lineinfile: dest={{ sonatype_nexus_root_dir }}/{{ nexus_directory.stdout }}/conf/nexus.properties 27 | regexp='^application-port=' 28 | line='application-port={{ sonatype_nexus_application_port }}' 29 | notify: 30 | - restart sonatype-nexus 31 | 32 | - name: Set application-host 33 | lineinfile: dest={{ sonatype_nexus_root_dir }}/{{ nexus_directory.stdout }}/conf/nexus.properties 34 | regexp='^application-host=' 35 | line='application-host={{ sonatype_nexus_application_host }}' 36 | notify: 37 | - restart sonatype-nexus 38 | 39 | - name: Set nexus-work 40 | lineinfile: dest={{ sonatype_nexus_root_dir }}/{{ nexus_directory.stdout }}/conf/nexus.properties 41 | regexp='^nexus-work=' 42 | line='nexus-work={{ sonatype_nexus_work_dir }}' 43 | notify: 44 | - restart sonatype-nexus 45 | 46 | - name: Set nexus-webapp-context-path 47 | lineinfile: dest={{ sonatype_nexus_root_dir }}/{{ nexus_directory.stdout }}/conf/nexus.properties 48 | regexp='^nexus-webapp-context-path=' 49 | line='nexus-webapp-context-path={{ sonatype_nexus_webapp_context_path }}' 50 | notify: 51 | - restart sonatype-nexus 52 | -------------------------------------------------------------------------------- /roles/sonatype-nexus/tasks/download.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Download nexus 3 | get_url: url={{ sonatype_nexus_download_url }} dest={{ sonatype_nexus_download_dest }} 4 | register: nexus_download 5 | 6 | - name: Get Nexus directory 7 | shell: "tar -tf {{ sonatype_nexus_download_dest }} | egrep '^nexus-' | cut -d/ -f1 | uniq" 8 | changed_when: false 9 | register: nexus_directory 10 | 11 | - name: Extract Nexus 12 | command: tar xzf {{ sonatype_nexus_download_dest }} chdir=/opt 13 | when: nexus_download.changed 14 | notify: 15 | - restart sonatype-nexus 16 | 17 | - name: Create and own working directories 18 | file: dest={{ item }} owner=nexus group=nexus recurse=true state=directory 19 | with_items: 20 | - "{{ sonatype_nexus_work_dir }}" 21 | - "{{ sonatype_nexus_work_dir }}/plugin-repository" 22 | - "{{ sonatype_nexus_pid_dir }}" 23 | - "{{ sonatype_nexus_root_dir }}/{{ nexus_directory.stdout }}/logs" 24 | notify: 25 | - restart sonatype-nexus 26 | -------------------------------------------------------------------------------- /roles/sonatype-nexus/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Create "nexus" group 3 | group: name=nexus 4 | 5 | - name: Create "nexus" user 6 | user: name=nexus group=nexus groups="sudo" 7 | 8 | - include: openjdk.yml 9 | 10 | - include: download.yml 11 | 12 | - include: configure.yml 13 | 14 | - include: startup.yml 15 | 16 | - include: nginx.yml 17 | -------------------------------------------------------------------------------- /roles/sonatype-nexus/tasks/nginx.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Install nginx 3 | apt: name=nginx state=installed 4 | notify: 5 | - restart nginx 6 | 7 | - name: Install SSL cert 8 | copy: src={{ sonatype_nexus_nginx_ssl_cert_file }} dest=/etc/ssl/certs/sonatype_nexus.crt 9 | owner=root group=root mode=0644 10 | when: sonatype_nexus_nginx_ssl == true 11 | notify: 12 | - restart nginx 13 | 14 | - name: Install SSL key 15 | copy: src={{ sonatype_nexus_nginx_ssl_key_file }} dest=/etc/ssl/private/sonatype_nexus.key 16 | owner=root group=root mode=0600 17 | when: sonatype_nexus_nginx_ssl == true 18 | notify: 19 | - restart nginx 20 | 21 | - name: Install nginx configuration 22 | template: src=nginx.conf.j2 dest=/etc/nginx/conf.d/sonatype_nexus.conf 23 | owner=root group=root mode=0644 24 | notify: 25 | - restart nginx 26 | -------------------------------------------------------------------------------- /roles/sonatype-nexus/tasks/openjdk.yml: -------------------------------------------------------------------------------- 1 | - name: Install OpenJDK 2 | apt: pkg="openjdk-7-jre" update_cache=yes 3 | -------------------------------------------------------------------------------- /roles/sonatype-nexus/tasks/startup.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: Repoint symbolic link 4 | file: src={{ sonatype_nexus_root_dir }}/{{ nexus_directory.stdout }} 5 | dest={{ sonatype_nexus_dir }} 6 | state=link 7 | notify: 8 | - restart sonatype-nexus 9 | 10 | - name: update nexus init-script 11 | copy: 12 | src: nexus.init 13 | dest: "{{ sonatype_nexus_dir }}/bin/nexus" 14 | mode: "u=rwx,g=rx,o=rx" 15 | 16 | - name: create symbolic links to /etc/init.d/nexus 17 | file: src={{ sonatype_nexus_dir }}/bin/nexus 18 | dest=/etc/init.d/nexus 19 | state=link 20 | notify: 21 | - restart sonatype-nexus 22 | 23 | - name: set permissions for nexus root dir 24 | file: path={{ sonatype_nexus_root_dir }}/{{ nexus_directory.stdout }} owner={{ sonatype_nexus_user }} group={{ sonatype_nexus_user }} state=directory recurse=yes 25 | 26 | - name: configure runlevel links for nexus 27 | service: name=nexus enabled=yes 28 | 29 | -------------------------------------------------------------------------------- /roles/sonatype-nexus/templates/nginx.conf.j2: -------------------------------------------------------------------------------- 1 | #{{ ansible_managed }} 2 | {% if sonatype_nexus_nginx_ssl == true %} 3 | server { 4 | server_name {{ sonatype_nexus_nginx_fqdn }}; 5 | listen 80{% if sonatype_nexus_nginx_default_site == true %} default{% endif %}; 6 | rewrite ^ https://$host$request_uri permanent; 7 | } 8 | 9 | {% endif %} 10 | server { 11 | server_name {{ sonatype_nexus_nginx_fqdn }}; 12 | listen {% if sonatype_nexus_nginx_ssl == true %}443{% else %}80{% endif %} 13 | {%- if sonatype_nexus_nginx_default_site == true %} default{% endif %} 14 | {%- if sonatype_nexus_nginx_ssl == true %} ssl{% endif %}; 15 | 16 | {% if sonatype_nexus_nginx_ssl == true %} 17 | ssl_certificate /etc/ssl/certs/sonatype_nexus.crt; 18 | ssl_certificate_key /etc/ssl/private/sonatype_nexus.key; 19 | {% endif %} 20 | 21 | location / { 22 | proxy_pass http://localhost:{{ sonatype_nexus_application_port }}; 23 | proxy_set_header Host $host; 24 | proxy_set_header X-Real-IP $remote_addr; 25 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 26 | {% if sonatype_nexus_nginx_ssl == true %} 27 | proxy_set_header X-Forwarded-Proto "https"; 28 | proxy_set_header X-Url-Scheme $scheme; 29 | {% endif %} 30 | proxy_redirect off; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /roles/sonatype-nexus/vars/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | sonatype_nexus_root_dir: "/opt" 3 | sonatype_nexus_dir: "{{ sonatype_nexus_root_dir }}/sonatype-nexus" 4 | sonatype_nexus_download_url: "http://www.sonatype.org/downloads/nexus-{{ sonatype_nexus_version }}-bundle.tar.gz" 5 | sonatype_nexus_download_dest: "{{ sonatype_nexus_root_dir }}/nexus-{{ sonatype_nexus_version }}-bundle.tar.gz" 6 | -------------------------------------------------------------------------------- /roles/zookeeper/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | zookeeper_user: zookeeper 4 | zookeeper_group: zookeeper 5 | 6 | zookeeper_exhibitor_download_url: "http://dl.bintray.com/warsjawa-microhackathon/3rd-party/{{ zookeeper_exhibitor_jar }}" 7 | zookeeper_exhibitor_dir: /srv/exhibitor 8 | zookeeper_exhibitor_logs: /var/log/exhibitor 9 | zookeeper_exhibitor_version: 1.5.1 10 | 11 | zookeeper_data_path: /var/lib/zookeeper 12 | zookeeper_version: 3.4.6 13 | zookeeper_apache_mirror: "http://ftp.ps.pl/pub/apache/zookeeper" 14 | -------------------------------------------------------------------------------- /roles/zookeeper/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: restart exhibitor 4 | service: 5 | name: exhibitor 6 | state: restarted 7 | -------------------------------------------------------------------------------- /roles/zookeeper/tasks/exhibitor.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: create zookeeper service group 4 | group: 5 | name: "{{ zookeeper_group }}" 6 | system: yes 7 | state: present 8 | 9 | - name: create zookeeper service user 10 | user: 11 | name: "{{ zookeeper_user }}" 12 | group: "{{ zookeeper_group }}" 13 | shell: /bin/false 14 | system: yes 15 | home: "{{ zookeeper_exhibitor_dir }}" 16 | 17 | - name: create exhibitor directories 18 | file: 19 | path: "{{ zookeeper_exhibitor_dir }}/{{ item }}" 20 | state: directory 21 | owner: "{{ zookeeper_user }}" 22 | group: "{{ zookeeper_group }}" 23 | with_items: 24 | - bin 25 | - conf 26 | - zookeeper 27 | 28 | - name: create exhibitor log directory 29 | file: 30 | path: "{{ zookeeper_exhibitor_logs }}" 31 | state: directory 32 | owner: "{{ zookeeper_user }}" 33 | group: "{{ zookeeper_group }}" 34 | 35 | - name: download exhibitor from Bintray 36 | get_url: 37 | url: "{{ zookeeper_exhibitor_download_url }}" 38 | dest: "{{ zookeeper_exhibitor_dir }}/bin" 39 | owner: "{{ zookeeper_user }}" 40 | group: "{{ zookeeper_group }}" 41 | 42 | - name: create exhibitor configuration 43 | template: 44 | src: exhibitor.properties.j2 45 | dest: "{{ zookeeper_exhibitor_dir }}/conf/exhibitor.properties" 46 | owner: "{{ zookeeper_user }}" 47 | group: "{{ zookeeper_group }}" 48 | notify: 49 | - restart exhibitor 50 | 51 | - name: create service configuration 52 | template: 53 | src: exhibitor.service.j2 54 | dest: /etc/systemd/system/exhibitor.service 55 | register: 56 | template_result 57 | notify: 58 | - restart exhibitor 59 | 60 | - name: reload systemd manager configuration 61 | command: 62 | systemctl daemon-reload 63 | when: 64 | template_result.changed 65 | 66 | - name: start and enable service 67 | service: 68 | name: exhibitor 69 | state: started 70 | enabled: yes 71 | 72 | -------------------------------------------------------------------------------- /roles/zookeeper/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - include: exhibitor.yml 4 | - include: zookeeper.yml 5 | -------------------------------------------------------------------------------- /roles/zookeeper/tasks/zookeeper.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: check if zookeeper is already installed 4 | stat: 5 | path: "{{ zookeeper_exhibitor_dir }}/zookeeper/{{ zookeeper_archive_name }}/bin/zkServer.sh" 6 | register: zookeeper_installed 7 | 8 | - name: download zookeeper 9 | get_url: 10 | url: "{{ zookeeper_download_url }}" 11 | dest: "/tmp/{{ zookeeper_archive_name }}.tgz" 12 | when: not zookeeper_installed.stat.exists 13 | 14 | - name: extract zookeeper archive 15 | unarchive: 16 | src: "/tmp/{{ zookeeper_archive_name }}.tgz" 17 | dest: "{{ zookeeper_exhibitor_dir }}/zookeeper" 18 | copy: no 19 | when: not zookeeper_installed.stat.exists 20 | 21 | - name: fix ownership 22 | file: 23 | path: "{{ zookeeper_exhibitor_dir }}/zookeeper/{{ zookeeper_archive_name }}" 24 | owner: "{{ zookeeper_user }}" 25 | group: "{{ zookeeper_group }}" 26 | state: directory 27 | recurse: yes 28 | when: not zookeeper_installed.stat.exists 29 | -------------------------------------------------------------------------------- /roles/zookeeper/templates/exhibitor.properties.j2: -------------------------------------------------------------------------------- 1 | com.netflix.exhibitor.zookeeper-data-directory={{ zookeeper_data_path }} 2 | com.netflix.exhibitor.zookeeper-install-directory={{ zookeeper_exhibitor_dir }}/zookeeper/* 3 | com.netflix.exhibitor-rolling.zookeeper-install-directory={{ zookeeper_exhibitor_dir }}/zookeeper/* 4 | com.netflix.exhibitor.auto-manage-instances=1 5 | -------------------------------------------------------------------------------- /roles/zookeeper/templates/exhibitor.service.j2: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Exibitor 3 | After=network.target 4 | 5 | [Service] 6 | User={{ zookeeper_user }} 7 | Group={{ zookeeper_group }} 8 | WorkingDirectory={{ zookeeper_exhibitor_dir }} 9 | ExecStart=/usr/bin/java -jar {{ zookeeper_exhibitor_dir }}/bin/{{ zookeeper_exhibitor_jar }} -c file --fsconfigdir {{ zookeeper_exhibitor_dir }}/conf 10 | ExecStop=/bin/kill -s TERM $MAINPID 11 | TimeoutSec=300 12 | 13 | [Install] 14 | WantedBy=multi-user.target 15 | -------------------------------------------------------------------------------- /roles/zookeeper/vars/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | zookeeper_exhibitor_jar: "exhibitor-{{ zookeeper_exhibitor_version }}.jar" 4 | zookeeper_archive_name: "zookeeper-{{ zookeeper_version }}" 5 | zookeeper_download_dest: "/tmp/{{ zookeeper_archive_name }}.tar.gz" 6 | zookeeper_download_url: "{{ zookeeper_apache_mirror }}/{{ zookeeper_archive_name }}/{{ zookeeper_archive_name }}.tar.gz" 7 | -------------------------------------------------------------------------------- /scripts/deploy-microservice.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Sample script used for microservice deployment 4 | 5 | [[ -z $DEBUG ]] || set -o xtrace 6 | 7 | log() { 8 | echo "[$(date +'%Y-%m-%dT%H:%M:%S%z')]: $*" 9 | } 10 | 11 | err() { 12 | log "$@" >&2 13 | } 14 | 15 | usage() { 16 | echo "usage: $( basename $0 ) groupId artifactId version nexusUrl" 17 | exit 1 18 | } 19 | 20 | DEPLOY_DIR="${RD_OPTION_DEPLOYDIR:-/srv/deploy}" 21 | CONFIG_FOLDER="${RD_OPTION_CONFIGFOLDER:-/srv/properties}" 22 | APP_ENV="${RD_OPTION_APPENV:-prod}" 23 | 24 | GROUP_ID="${RD_OPTION_GROUPID:-$1}" 25 | ARTIFACT_ID="${RD_OPTION_ARTIFACTID:-$2}" 26 | VERSION="${RD_OPTION_VERSION:-$3}" 27 | NEXUS_URL="${RD_OPTION_NEXUSURL:-$4}" 28 | 29 | JAVA_OPTS="-Dspring.profiles.active=prod" 30 | 31 | export APP_ENV CONFIG_FOLDER 32 | 33 | if [[ -z "${GROUP_ID}" ]]; then 34 | err "Missing groupID" 35 | usage 36 | fi 37 | 38 | if [[ -z "${ARTIFACT_ID}" ]]; then 39 | err "Missing artifactId" 40 | usage 41 | fi 42 | 43 | if [[ -z "${VERSION}" ]]; then 44 | err "Missing version" 45 | usage 46 | fi 47 | 48 | if [[ -z "${NEXUS_URL}" ]]; then 49 | err "Missing nexusUrl" 50 | usage 51 | fi 52 | 53 | if [[ ! -d "${CONFIG_FOLDER}/.git" ]]; then 54 | err "CONFIG_FOLDER should be git repo" 55 | exit 1 56 | fi 57 | 58 | log "Updating properties repository..." 59 | cd "${CONFIG_FOLDER}" && ( git fetch && git reset --hard origin/master ) 60 | 61 | ARTIFACT_URL="${NEXUS_URL}/${GROUP_ID//.//}/${ARTIFACT_ID}/${VERSION}/${ARTIFACT_ID}-${VERSION}.jar" 62 | 63 | APP_DIR="${DEPLOY_DIR}/${ARTIFACT_ID}" 64 | JAR_FILE="${APP_DIR}/${ARTIFACT_ID}.jar" 65 | 66 | mkdir -p "${APP_DIR}" 67 | 68 | log "Downloading artifact..." 69 | wget "${ARTIFACT_URL}" -O "${JAR_FILE}" 70 | 71 | # start microservice 72 | if [[ -f "${APP_DIR}/${ARTIFACT_ID}.pid" ]]; then 73 | PID="$( cat "${APP_DIR}/${ARTIFACT_ID}.pid" )" 74 | log "Killing ${PID}..." 75 | if ! kill -9 "${PID}" ; then 76 | echo "No process killed" 77 | fi 78 | fi 79 | 80 | log "Starting ${JAR_FILE}" 81 | cd "${APP_DIR}" 82 | exec nohup java ${JAVA_OPTS} -jar "${JAR_FILE}" /dev/null & 83 | echo $! > "${ARTIFACT_ID}.pid" 84 | -------------------------------------------------------------------------------- /site.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: openssl 4 | hosts: localhost 5 | connection: local 6 | gather_facts: false 7 | vars_files: 8 | - hackathons/default.yml 9 | - hackathons/{{ hackathon_edition }}.yml 10 | tasks: 11 | - name: generate certificates for logstash forwarder 12 | command: > 13 | openssl req -days 356 -x509 -batch -nodes -newkey rsa:2048 14 | -keyout {{ logstash_forwarder_key }} 15 | -out {{ logstash_forwarder_cert }} 16 | -subj '/C=PL/ST=mazowieckie/L=Warszawa/CN={{ logstash_lumberjack_host }}' 17 | args: 18 | creates: "{{ logstash_forwarder_cert }}" 19 | - name: generate SSH keys for rundeck 20 | command: > 21 | ssh-keygen -q -N "" -f {{ rundeck_ssh_private_key }} 22 | args: 23 | creates: "{{ rundeck_ssh_private_key }}" 24 | 25 | - name: sshd 26 | hosts: all 27 | gather_facts: false 28 | tasks: 29 | - name: Wait for sshd to be running 30 | local_action: "wait_for host={{ inventory_hostname }} delay=0 port={{ ansible_ssh_port|default(22) }} timeout=90 state=started" 31 | when: is_vagrant is not defined 32 | 33 | - name: Server for applications 34 | hosts: apps 35 | sudo: yes 36 | vars_files: 37 | - hackathons/default.yml 38 | - hackathons/{{ hackathon_edition }}.yml 39 | roles: 40 | - { role: common } 41 | - { role: deploy } 42 | - { role: oracle_jdk, oracle_jdk_version: '8u5-b13' } 43 | - { role: zookeeper } 44 | - { role: logstash_forwarder } 45 | - { role: hystrix_dashboard } 46 | 47 | - name: Server for monitoring 48 | hosts: monitoring 49 | sudo: true 50 | vars_files: 51 | - hackathons/default.yml 52 | - hackathons/{{ hackathon_edition }}.yml 53 | roles: 54 | - { role: common } 55 | - { role: apache } 56 | - { role: elasticsearch } 57 | - { role: logstash } 58 | - { role: kibana } 59 | - { role: graphite } 60 | - { role: grafana } 61 | - { role: seyren } 62 | 63 | - name: Server for nexus 64 | hosts: nexus 65 | sudo: true 66 | vars_files: 67 | - hackathons/default.yml 68 | - hackathons/{{ hackathon_edition }}.yml 69 | roles: 70 | - { role: common } 71 | - { role: sonatype-nexus } 72 | 73 | - name: Server for Jenkins 74 | hosts: jenkins 75 | sudo: true 76 | vars_files: 77 | - hackathons/default.yml 78 | - hackathons/{{ hackathon_edition }}.yml 79 | roles: 80 | - { role: common } 81 | - { role: oracle_jdk, oracle_jdk_version: '8u5-b13' } 82 | - { role: jenkins } 83 | - { role: jenkins_seed_job } 84 | 85 | - name: Server for Rundeck 86 | hosts: rundeck 87 | sudo: true 88 | vars_files: 89 | - hackathons/default.yml 90 | - hackathons/{{ hackathon_edition }}.yml 91 | roles: 92 | - { role: common } 93 | - { role: rundeck } 94 | --------------------------------------------------------------------------------