Skip to content

Commit 401f7e0

Browse files
committed
Initial commit
1 parent 119f8a6 commit 401f7e0

File tree

9 files changed

+403
-2
lines changed

9 files changed

+403
-2
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/.idea/

README.md

Lines changed: 268 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,268 @@
1-
# ansible-jenkins
2-
Ansible role to install and fully configure Jenkins CI in Docker
1+
Ansible Role for Jenkins
2+
========================
3+
4+
Installs and optionally configures Jenkins using Ansible.
5+
6+
Requirements
7+
------------
8+
9+
Requires curl to be installed on the server.
10+
11+
If deploying using Docker then you need Docker
12+
installed on the server.
13+
14+
(Docker is the only supported way at the moment
15+
although more ways can easily be added, PRs welcome).
16+
17+
Installation
18+
------------
19+
20+
Install using ansible galaxy:
21+
22+
```
23+
$ ansible-galaxy install emmetog.jenkins
24+
```
25+
26+
Role Variables
27+
--------------
28+
29+
```yml
30+
jenkins_version: "1.642.4" # The exact version of jenkins to deploy
31+
jenkins_url: "http://127.0.0.1" # The url that Jenkins will be accessible on
32+
jenkins_port: "8080" # The port that Jenkins will listen on
33+
jenkins_home: /data/jenkins # The directory on the server where the Jenkins configs will live
34+
35+
# If you need to override any java options then do that here.
36+
jenkins_java_opts: "-Djenkins.install.runSetupWizard=false"
37+
38+
# The locations of the configuration files for jenkins
39+
jenkins_source_dir_configs: "{{ playbook_dir }}/jenkins-configs"
40+
jenkins_source_dir_jobs: "{{ jenkins_source_dir_configs }}/jobs"
41+
42+
# The names of the jobs (an xml must exist in jenkins_source_dir_jobs with these names)
43+
jenkins_jobs: []
44+
45+
# These plugins will be installed in the jenkins instance
46+
jenkins_plugins:
47+
- git
48+
- log-parser
49+
- copyartifact
50+
- workflow-aggregator
51+
- workflow-multibranch
52+
- docker-workflow
53+
- template-project
54+
- ec2
55+
56+
# Configs specific to the "docker" method of running jenkins
57+
jenkins_docker_container_name: jenkins
58+
```
59+
60+
Example Playbook
61+
----------------
62+
63+
```yml
64+
- hosts: jenkins
65+
66+
vars:
67+
jenkins_version: "1.642.4"
68+
jenkins_url: http://jenkins.example.com
69+
jenkins_port: 80
70+
jenkins_install_via: "docker"
71+
jenkins_jobs: [
72+
"my-cool-job",
73+
"another-awesome-job"
74+
]
75+
76+
roles:
77+
- emmetog.jenkins
78+
```
79+
80+
Jenkins Configs
81+
---------------
82+
83+
The example above will look for the job configs in
84+
`{{ playbook_dir }}/jenkins-configs/jobs/my-cool-job.xml` and
85+
`{{ playbook_dir }}/jenkins-configs/jobs/another-awesome-job.xml`.
86+
It will also look for `{{ playbook_dir }}/jenkins-configs/config.xml` and
87+
`{{ playbook_dir }}/jenkins-configs/credentials.xml`.
88+
These configs will be templated over to the server to be used
89+
as the job configuration.
90+
91+
***NOTE***: These directories are customizable, see the `jenkins_source_dir_configs`
92+
and `jenkins_source_dir_jobs` role variables.
93+
94+
All the configs are templated so you can put variables in them,
95+
for example it would be a good idea to encrypt sensitive variables
96+
in ansible vault.
97+
98+
Example Job Configs
99+
-------------------
100+
101+
Here's an example of what you could put in `{{ playbook_dir }}/jenkins-configs/jobs/my-cool-job.xml`:
102+
103+
```xml
104+
<?xml version='1.0' encoding='UTF-8'?>
105+
<flow-definition plugin="workflow-job@2.2">
106+
<actions/>
107+
<description>My Cool Job</description>
108+
<keepDependencies>false</keepDependencies>
109+
<properties/>
110+
<definition class="org.jenkinsci.plugins.workflow.cps.CpsScmFlowDefinition" plugin="workflow-cps@2.4">
111+
<scm class="hudson.plugins.git.GitSCM" plugin="git@2.4.4">
112+
<configVersion>2</configVersion>
113+
<userRemoteConfigs>
114+
<hudson.plugins.git.UserRemoteConfig>
115+
<url>git@github.com:emmetog/ansible-jenkins.git</url>
116+
<credentialsId>github-deploy-key-jenkins</credentialsId>
117+
</hudson.plugins.git.UserRemoteConfig>
118+
</userRemoteConfigs>
119+
<branches>
120+
<hudson.plugins.git.BranchSpec>
121+
<name>*/master</name>
122+
</hudson.plugins.git.BranchSpec>
123+
</branches>
124+
<doGenerateSubmoduleConfigurations>false</doGenerateSubmoduleConfigurations>
125+
<submoduleCfg class="list"/>
126+
<extensions/>
127+
</scm>
128+
<scriptPath>Jenkinsfile</scriptPath>
129+
</definition>
130+
<triggers/>
131+
</flow-definition>
132+
```
133+
134+
Example Jenkins Configs
135+
-----------------------
136+
137+
In `{{ jenkins_source_dir_configs }}/config.xml` you put your global
138+
Jenkins configuration, for example:
139+
```xml
140+
<?xml version='1.0' encoding='UTF-8'?>
141+
<hudson>
142+
<disabledAdministrativeMonitors/>
143+
<version></version>
144+
<numExecutors>2</numExecutors>
145+
<mode>NORMAL</mode>
146+
<useSecurity>true</useSecurity>
147+
<authorizationStrategy class="hudson.security.AuthorizationStrategy$Unsecured"/>
148+
<securityRealm class="hudson.security.SecurityRealm$None"/>
149+
<disableRememberMe>false</disableRememberMe>
150+
<projectNamingStrategy class="jenkins.model.ProjectNamingStrategy$DefaultProjectNamingStrategy"/>
151+
<workspaceDir>${ITEM_ROOTDIR}/workspace</workspaceDir>
152+
<buildsDir>${ITEM_ROOTDIR}/builds</buildsDir>
153+
<jdks/>
154+
<viewsTabBar class="hudson.views.DefaultViewsTabBar"/>
155+
<myViewsTabBar class="hudson.views.DefaultMyViewsTabBar"/>
156+
<clouds>
157+
<hudson.plugins.ec2.EC2Cloud plugin="ec2@1.33">
158+
<name>ec2-slave-docker-ec2</name>
159+
<useInstanceProfileForCredentials>false</useInstanceProfileForCredentials>
160+
<credentialsId>jenkins-aws-ec2</credentialsId>
161+
162+
<privateKey class="com.cloudbees.jenkins.plugins.sshcredentials.impl.BasicSSHUserPrivateKey$DirectEntryPrivateKeySource">
163+
<privateKey>{{ ssh_jenkins_aws_key }}</privateKey>
164+
</privateKey>
165+
166+
<instanceCap>1</instanceCap>
167+
<templates>
168+
<hudson.plugins.ec2.SlaveTemplate>
169+
<ami>ami-2654d755</ami>
170+
<description>Docker builder</description>
171+
<zone>eu-west-1c</zone>
172+
<securityGroups>ssh-only</securityGroups>
173+
<remoteFS></remoteFS>
174+
<type>T2Micro</type>
175+
<ebsOptimized>false</ebsOptimized>
176+
<labels>docker</labels>
177+
<mode>NORMAL</mode>
178+
<initScript></initScript>
179+
<tmpDir></tmpDir>
180+
<userData></userData>
181+
<numExecutors>1</numExecutors>
182+
<remoteAdmin>ubuntu</remoteAdmin>
183+
<jvmopts></jvmopts>
184+
<subnetId></subnetId>
185+
<idleTerminationMinutes>30</idleTerminationMinutes>
186+
<iamInstanceProfile></iamInstanceProfile>
187+
<useEphemeralDevices>false</useEphemeralDevices>
188+
<customDeviceMapping></customDeviceMapping>
189+
<instanceCap>2147483647</instanceCap>
190+
<stopOnTerminate>true</stopOnTerminate>
191+
<usePrivateDnsName>false</usePrivateDnsName>
192+
<associatePublicIp>false</associatePublicIp>
193+
<useDedicatedTenancy>false</useDedicatedTenancy>
194+
<amiType class="hudson.plugins.ec2.UnixData">
195+
<rootCommandPrefix></rootCommandPrefix>
196+
<sshPort>22</sshPort>
197+
</amiType>
198+
<launchTimeout>2147483647</launchTimeout>
199+
<connectBySSHProcess>false</connectBySSHProcess>
200+
<connectUsingPublicIp>false</connectUsingPublicIp>
201+
</hudson.plugins.ec2.SlaveTemplate>
202+
</templates>
203+
<region>eu-west-1</region>
204+
</hudson.plugins.ec2.EC2Cloud>
205+
</clouds>
206+
<quietPeriod>5</quietPeriod>
207+
<scmCheckoutRetryCount>0</scmCheckoutRetryCount>
208+
<views>
209+
<hudson.model.AllView>
210+
<owner class="hudson" reference="../../.."/>
211+
<name>All</name>
212+
<filterExecutors>false</filterExecutors>
213+
<filterQueue>false</filterQueue>
214+
<properties class="hudson.model.View$PropertyList"/>
215+
</hudson.model.AllView>
216+
</views>
217+
<primaryView>All</primaryView>
218+
<slaveAgentPort>50000</slaveAgentPort>
219+
<label></label>
220+
<nodeProperties/>
221+
<globalNodeProperties/>
222+
</hudson>
223+
```
224+
225+
In `{{ jenkins_source_dir_configs }}/credentials.xml` you put any
226+
credentials that you need, for example:
227+
```xml
228+
<?xml version='1.0' encoding='UTF-8'?>
229+
<com.cloudbees.plugins.credentials.SystemCredentialsProvider plugin="credentials@1.24">
230+
<domainCredentialsMap class="hudson.util.CopyOnWriteMap$Hash">
231+
<entry>
232+
<com.cloudbees.plugins.credentials.domains.Domain>
233+
<specifications/>
234+
</com.cloudbees.plugins.credentials.domains.Domain>
235+
<java.util.concurrent.CopyOnWriteArrayList>
236+
237+
<com.cloudbees.jenkins.plugins.sshcredentials.impl.BasicSSHUserPrivateKey plugin="ssh-credentials@1.12">
238+
<scope>GLOBAL</scope>
239+
<id>github-deploy-key-jenkins</id>
240+
<description>github-deploy-key-jenkins</description>
241+
<username>git</username>
242+
<passphrase></passphrase>
243+
<privateKeySource class="com.cloudbees.jenkins.plugins.sshcredentials.impl.BasicSSHUserPrivateKey$DirectEntryPrivateKeySource">
244+
<privateKey>{{ github_jenkins_deploy_key }}</privateKey>
245+
</privateKeySource>
246+
</com.cloudbees.jenkins.plugins.sshcredentials.impl.BasicSSHUserPrivateKey>
247+
248+
</java.util.concurrent.CopyOnWriteArrayList>
249+
</entry>
250+
</domainCredentialsMap>
251+
</com.cloudbees.plugins.credentials.SystemCredentialsProvider>
252+
```
253+
254+
License
255+
-------
256+
257+
MIT
258+
259+
Author Information
260+
------------------
261+
262+
Made with love by Emmet O'Grady.
263+
264+
I am the founder of [NimbleCI](https://nimbleci.com) which
265+
builds Docker containers for feature branch workflow projects in Github.
266+
267+
I blog on my [personal blog](http://blog.emmetogrady.com) and
268+
about Docker related things on the [NimbleCI blog](https://blog.nimbleci.com).

defaults/main.yml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
---
2+
3+
jenkins_version: "1.642.4" # The exact version of jenkins to deploy
4+
jenkins_url: "http://127.0.0.1" # The url that Jenkins will be accessible on
5+
jenkins_port: "8080" # The port that Jenkins will listen on
6+
jenkins_home: /data/jenkins # The directory on the server where the Jenkins configs will live
7+
8+
# If you need to override any java options then do that here.
9+
jenkins_java_opts: "-Djenkins.install.runSetupWizard=false"
10+
11+
# The locations of the configuration files for jenkins
12+
jenkins_source_dir_configs: "{{ playbook_dir }}/jenkins-configs"
13+
jenkins_source_dir_jobs: "{{ jenkins_source_dir_configs }}/jobs"
14+
15+
# The names of the jobs (an xml must exist in jenkins_source_dir_jobs with these names)
16+
jenkins_jobs: []
17+
18+
# These plugins will be installed in the jenkins instance
19+
jenkins_plugins:
20+
- git
21+
- log-parser
22+
- copyartifact
23+
- workflow-aggregator
24+
- workflow-multibranch
25+
- docker-workflow
26+
- template-project
27+
- ec2
28+
29+
# Configs specific to the "docker" method of running jenkins
30+
jenkins_docker_container_name: jenkins

tasks/configure-jenkins.yml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
---
2+
3+
- name: Configuration file is up to date (config.xml)
4+
template:
5+
src: "{{ jenkins_source_dir_configs }}/config.xml"
6+
dest: "{{ jenkins_home }}/config.xml"
7+
mode: "0770"
8+
9+
- name: Configuration file is up to date (credentials.xml)
10+
template:
11+
src: "{{ jenkins_source_dir_configs }}/credentials.xml"
12+
dest: "{{ jenkins_home }}/credentials.xml"
13+
mode: "0770"
14+
15+
- name: Plugins are installed
16+
shell: "curl -X POST \
17+
-d '<jenkins><install plugin=\"{{ item }}@latest\" /></jenkins>' \
18+
--header 'Content-Type: text/xml' \
19+
{{ jenkins_url }}:{{ jenkins_port }}/pluginManager/installNecessaryPlugins"
20+
args:
21+
creates: "{{ jenkins_home }}/plugins/{{ item }}"
22+
with_items: jenkins_plugins
23+
register: plugins_result
24+
25+
- wait_for:
26+
path: "{{jenkins_home }}/plugins/{{ item }}"
27+
with_items: jenkins_plugins

tasks/configure-jobs.yml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
---
2+
3+
- name: Job directories are present
4+
file:
5+
path: "{{ jenkins_home }}/jobs/{{ item }}"
6+
state: directory
7+
mode: 0777
8+
with_items: jenkins_jobs
9+
10+
- name: Jobs are present
11+
template:
12+
src: "{{ jenkins_source_dir_jobs }}/{{ item }}.xml"
13+
dest: "{{ jenkins_home }}/jobs/{{ item }}/config.xml"
14+
mode: 0777
15+
with_items: jenkins_jobs
16+
17+
- name: Jenkins is reloaded
18+
uri:
19+
url: "{{ jenkins_url }}:{{ jenkins_port }}/reload"
20+
method: POST
21+
status_code: 200,302
22+
ignore_errors: yes

tasks/docker/install.yml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
---
2+
3+
- name: Ensure jenkins home dir is created
4+
file:
5+
path: "{{ jenkins_home }}"
6+
mode: 0777
7+
recurse: yes
8+
state: directory
9+
10+
- name: Container is running
11+
docker:
12+
name: "{{ jenkins_docker_container_name }}"
13+
image: "jenkins:{{ jenkins_version }}"
14+
ports: "{{ jenkins_port }}:8080"
15+
volumes:
16+
- "{{ jenkins_home }}:/var/jenkins_home"
17+
env:
18+
JAVA_OPTS: "{{ jenkins_java_opts }}"
19+
register: container_result
20+
21+
- pause: seconds=45
22+
when: container_result|changed

0 commit comments

Comments
 (0)