OSDN Git Service

665d66df23799f9a6a8e4b9a2b0224d346cf692e
[metasearch/grid-chef-repo.git] / cookbooks / concourse-ci / README.md
1 concourse-ci Cookbook
2 =====================
3
4 This cookbook sets up a Concourse CI service by Docker Compose.
5
6 ## Contents
7
8 - [Requirements](#requirements)
9     - [platforms](#platforms)
10     - [packages](#packages)
11     - [cookbooks](#cookbooks)
12 - [Attributes](#attributes)
13 - [Usage](#usage)
14     - [Recipes](#recipes)
15         - [concourse-ci::default](#concourse-cidefault)
16         - [concourse-ci::fly](#concourse-cifly)
17         - [concourse-ci::docker-compose](#concourse-cidocker-compose)
18     - [Role Examples](#role-examples)
19     - [SSL server keys and certificates management by ssl_cert cookbook](#ssl-server-keys-and-certificates-management-by-ssl_cert-cookbook)
20     - [Encryption key management by Chef Vault](#encryption-key-management-by-chef-vault)
21     - [OAuth client ID and secret management by Chef Vault](#oauth-client-id-and-secret-management-by-chef-vault)
22 - [License and Authors](#license-and-authors)
23
24 ## Requirements
25
26 ### platforms
27 - none.
28
29 ### packages
30 - none.
31
32 ### cookbooks
33 - `docker-grid`
34 - `ssl_cert`
35
36 ## Attributes
37
38 |Key|Type|Description, example|Default|
39 |:--|:--|:--|:--|
40 |`['concourse-ci']['fly']['version']`|String||`'3.3.4'`|
41 |`['concourse-ci']['fly']['release_url']`|String||`"https://github.com/concourse/concourse/releases/download/v#{node['concourse-ci']['fly']['version']}/fly_linux_amd64"`|
42 |`['concourse-ci']['fly']['release_checksum']`|String||`nil`|
43 |`['concourse-ci']['fly']['auto_upgrade']`|Boolean||`false`|
44 |`['concourse-ci']['fly']['install_path']`|String||`'/usr/local/bin/fly'`|
45 |`['concourse-ci']['with_ssl_cert_cookbook']`|Boolean|See `attributes/default.rb`|`false`|
46 |`['concourse-ci']['ssl_cert']['ca_names']`|Array|Internal CA names that are imported by the ssl_cert cookbook.|`[]`|
47 |`['concourse-ci']['ssl_cert']['common_name']`|String|Server common name for TLS|`node['fqdn']`|
48 |`['concourse-ci']['docker-image']['entrypoint']`|String|Concourse Docker image's entrypoint setting to import an internal CA certificate.|`'/usr/local/bin/dumb-init /usr/local/bin/concourse'`|
49 |`['concourse-ci']['docker-compose']['import_ca']`|Boolean|whether import internal CA certificates or not.|`false`|
50 |`['concourse-ci']['docker-compose']['app_dir']`|String||`"#{node['docker-grid']['compose']['app_dir']}/concourse"`|
51 |`['concourse-ci']['docker-compose']['pgdata_dir']`|String|Path string or nil (unset).|`"#{node['concourse-ci']['docker-compose']['app_dir']}/database"`|
52 |`['concourse-ci']['docker-compose']['web_keys_dir']`|String|Path string.|`"#{node['concourse-ci']['docker-compose']['app_dir']}/keys/web"`|
53 |`['concourse-ci']['docker-compose']['worker_keys_dir']`|String|Path string.|`"#{node['concourse-ci']['docker-compose']['app_dir']}/keys/worker"`|
54 |`['concourse-ci']['docker-compose']['pgdata_dir']`|String|Path string or nil (unset, non-persistent).|`"#{node['concourse-ci']['docker-compose']['app_dir']}/database"`|
55 |`['concourse-ci']['docker-compose']['db_password_reset']`|String|Only available if the password is automatically generated by Chef.|`false`|
56 |`['concourse-ci']['docker-compose']['db_password_vault_item']`|Hash|See `attributes/default.rb`|`{}`|
57 |`['concourse-ci']['docker-compose']['web_encryption_key_vault_item']`|Hash|See `attributes/default.rb`|`{}`|
58 |`['concourse-ci']['docker-compose']['web_password_reset']`|String|Only available if the password is automatically generated by Chef.|`false`|
59 |`['concourse-ci']['docker-compose']['web_password_vault_item']`|Hash|See `attributes/default.rb`|`{}`|
60 |`['concourse-ci']['docker-compose']['web_oauth_client_id_vault_item']`|Hash|See `attributes/default.rb`|`{}`|
61 |`['concourse-ci']['docker-compose']['web_oauth_client_secret_vault_item']`|Hash|See `attributes/default.rb`|`{}`|
62 |`['concourse-ci']['docker-compose']['ssh_keys_reset']`|String|Resets all SSH keys forcely.|`false`|
63 |`['concourse-ci']['docker-compose']['config_format_version']`|String|`docker-compose.yml` format version. `'1'` or `'2'`|`'1'`|
64 |`['concourse-ci']['docker-compose']['config']`|Hash|`docker-compose.yml` configurations.|See `attributes/default.rb`|
65
66 ## Usage
67
68 ### Recipes
69
70 #### concourse-ci::default
71
72 This recipe does nothing.
73
74 #### concourse-ci::fly
75
76 This recipe installs the `fly` CLI and the `fly_prune_workers` command.
77
78 #### concourse-ci::docker-compose
79
80 This recipe generates SSH keys of each node and a `docker-compose.yml` file for the Concourse CI service.
81
82 ### Role Examples
83
84 - `roles/concourse.rb`
85
86 ```ruby
87 name 'concourse'
88 description 'Concourse'
89
90 run_list(
91   'role[docker]',
92   'recipe[concourse-ci::docker-compose]',
93 )
94
95 image = 'concourse/concourse:latest'
96 port = '18080'
97
98 override_attributes(
99   'concourse-ci' => {
100     'docker-compose' => {
101       'config' => {
102         # Version 1 docker-compose format
103         'concourse-web' => {
104           'image' => image,
105           'ports' => [
106             "#{port}:8080",
107           ],
108           #'volumes' => [
109           #  # These volumes will be set by the concourse-ci::docker-compose recipe automatically.
110           #  #"#{node['concourse-ci']['docker-compose']['web_keys_dir']}:/concourse-keys",
111           #],
112           'environment' => {
113             'CONCOURSE_EXTERNAL_URL' => "http://192.168.1.3:#{port}",
114             #'CONCOURSE_RESOURCE_CHECKING_INTERVAL' => '1m',  # default
115           },
116         },
117         'concourse-worker' => {
118           'image' => image,
119           #'volumes' => [
120           #  # These volumes will be set by the concourse-ci::docker-compose recipe automatically.
121           #  #"#{node['concourse-ci']['docker-compose']['worker_keys_dir']}:/concourse-keys",
122           #],
123         },
124       },
125     },
126   },
127 )
128 ```
129
130 - `roles/concourse-with-ssl.rb`
131
132 ```ruby
133 name 'concourse-with-ssl'
134 description 'Concourse with SSL'
135
136 run_list(
137   #'recipe[ssl_cert::server_key_pairs]',  # concourse-ci cookbook < 0.2.2
138   'role[docker]',
139   'recipe[concourse-ci::docker-compose]',
140 )
141
142 image = 'concourse/concourse:2.6.0'
143 port = '18443'
144 cn = 'concourse.io.example.com'
145
146 override_attributes(
147   'ssl_cert' => {
148     #'common_names' => [
149     #  cn,  # concourse-ci cookbook < 0.2.3
150     #],
151   },
152   'concourse-ci' => {
153     'with_ssl_cert_cookbook' => true,
154     'ssl_cert' => {
155       'common_name' => cn,
156     },
157     'docker-compose' => {
158       'config' => {
159         # Version 1 docker-compose format
160         'concourse-web' => {
161           'image' => image,
162           'ports' => [
163             "#{port}:8443",
164           ],
165           'environment' => {
166             'CONCOURSE_EXTERNAL_URL' => "https://192.168.1.3:#{port}",
167             'CONCOURSE_TLS_BIND_PORT' => '8443',  # activate HTTPS
168             # These environments will be set by the concourse-ci::docker-compose recipe automatically.
169             #'CONCOURSE_TLS_CERT' => '/root/server.crt',
170             #'CONCOURSE_TLS_KEY' => '/root/server.key',
171           },
172           #'volumes' => [
173           #  # These volumes will be set by the concourse-ci::docker-compose recipe automatically.
174           #  #"#{node['concourse-ci']['docker-compose']['web_keys_dir']}:/concourse-keys",
175           #  #"#{server_cert_path(node['concourse-ci']['ssl_cert']['common_name'])}:/root/server.crt:ro",
176           #  #"#{server_key_path(node['concourse-ci']['ssl_cert']['common_name'])}:/root/server.key:ro",
177           #],
178         },
179         'concourse-worker' => {
180           'image' => image,
181           #'volumes' => [
182           #  # These volumes will be set by the concourse-ci::docker-compose recipe automatically.
183           #  #"#{node['concourse-ci']['docker-compose']['worker_keys_dir']}:/concourse-keys",
184           #],
185         },
186       },
187     },
188   },
189 )
190 ```
191
192 - `roles/concourse-with-oauth.rb`
193
194 ```ruby
195 name 'concourse-with-oauth'
196 description 'Concourse with OAuth'
197
198 run_list(
199   #'recipe[ssl_cert::ca_certs]',  # concourse-ci cookbook < 0.2.2
200   'recipe[ssl_cert::server_key_pairs]',
201   'role[docker]',
202   'recipe[concourse-ci::docker-compose]',
203 )
204
205 image = 'concourse/concourse:latest'
206 port = '18443'
207 ca_name = 'grid_ca'
208 cn = 'concourse.io.example.com'
209 gitlab_cn = 'gitlab.io.example.com'
210
211 override_attributes(
212   'ssl_cert' => {
213     #'ca_names' => [
214     #  ca_name,  # concourse-ci cookbook < 0.2.3
215     #],
216     #'common_names' => [
217     #  cn,  # concourse-ci cookbook < 0.2.3
218     #],
219   },
220   'concourse-ci' => {
221     'with_ssl_cert_cookbook' => true,
222     'ssl_cert' => {
223       'ca_names' => [
224         ca_name,
225       ],
226       'common_name' => cn,
227     },
228     'docker-compose' => {
229       'import_ca' => true,
230       'web_oauth_client_id_vault_item' => {
231         'vault' => 'concourse',
232         'name' => 'web_oauth_client_id',
233         'env_context' => false,
234         'key' => 'cid',
235       },
236       'web_oauth_client_secret_vault_item' => {
237         'vault' => 'concourse',
238         'name' => 'web_oauth_client_secret',
239         'env_context' => false,
240         'key' => 'secret',
241       },
242       'config' => {
243         # Version 1 docker-compose format
244         'concourse-web' => {
245           'ports' => [
246             #'4080:8080',
247             "#{port}:8443",
248           ],
249           'environment' => {
250             'CONCOURSE_TLS_BIND_PORT' => '8443',
251             'CONCOURSE_EXTERNAL_URL' => "https://#{cn}:#{port}",
252             # OAuth for the default `main`` team
253             'CONCOURSE_GENERIC_OAUTH_DISPLAY_NAME' => 'GitLab',
254             # The following 2 variables are set automatically,
255             # if the ['concourse-ci']['docker-compose']['web_oauth_client_(id|secret)_vault_item'] attributes are specified.
256             #'CONCOURSE_GENERIC_OAUTH_CLIENT_ID' => '${CONCOURSE_GENERIC_OAUTH_CLIENT_ID}',
257             #'CONCOURSE_GENERIC_OAUTH_CLIENT_SECRET' => '${CONCOURSE_GENERIC_OAUTH_CLIENT_SECRET}',
258             'CONCOURSE_GENERIC_OAUTH_AUTH_URL' => "https://#{gitlab_cn}/oauth/authorize",
259             'CONCOURSE_GENERIC_OAUTH_TOKEN_URL' => "https://#{gitlab_cn}/oauth/token",
260           },
261         },
262       },
263     },
264   },
265 )
266 ```
267
268 ### SSL server keys and certificates management by ssl_cert cookbook
269
270 - create vault items.
271
272 ```text
273 $ ruby -rjson -e 'puts JSON.generate({"private" => File.read("concourse.io.example.com.prod.key")})' \
274 > > ~/tmp/concourse.io.example.com.prod.key.json
275
276 $ ruby -rjson -e 'puts JSON.generate({"public" => File.read("concourse.io.example.com.prod.crt")})' \
277 > > ~/tmp/concourse.io.example.com.prod.crt.json
278
279 $ cd $CHEF_REPO_PATH
280
281 $ knife vault create ssl_server_keys concourse.io.example.com.prod \
282 > --json ~/tmp/concourse.io.example.com.prod.key.json
283
284 $ knife vault create ssl_server_certs concourse.io.example.com.prod \
285 > --json ~/tmp/concourse.io.example.com.prod.crt.json
286 ```
287
288 - grant reference permission to the Concourse host
289
290 ```text
291 $ knife vault update ssl_server_keys  concourse.io.example.com.prod -S 'name:concourse-host.example.com'
292 $ knife vault update ssl_server_certs concourse.io.example.com.prod -S 'name:concourse-host.example.com'
293 ```
294
295 - modify run_list and attributes
296
297 ```ruby
298 run_list(
299   #'recipe[ssl_cert::server_key_pairs]',  # concourse-ci cookbook < 0.2.2
300   'recipe[concourse-ci::docker-compose]',
301 )
302
303 override_attributes(
304   'ssl_cert' => {
305     #'common_names' => [
306     #  'concourse.io.example.com',  # concourse-ci cookbook < 0.2.3
307     #],
308   },
309   'concourse-ci' => {
310     'with_ssl_cert_cookbook' => true,
311     'ssl_cert' => {
312       'common_name' => 'concourse.io.example.com',
313     },
314     # ...
315   },
316 )
317 ```
318
319 ### Encryption key management by Chef Vault
320
321 - create vault items.
322
323 ```text
324 # a 16 or 32-byte random character sequence.
325 $ cat ~/tmp/concourse_ekey.json
326 {"ekey":"********************************"}
327
328 $ knife vault create concourse web_encryption_key --json ~/tmp/concourse_ekey.json
329 ```
330
331 - grant reference permission to the Concourse host
332
333 ```text
334 $ knife vault update concourse web_encryption_key -S 'name:concourse-host.example.com'
335 ```
336
337 - modify attributes
338
339 ```ruby
340 override_attributes(
341   'concourse-ci' => {
342     # ...
343     'docker-compose' => {
344       'web_encryption_key_vault_item' => {
345         'vault' => 'concourse',
346         'name' => 'web_encryption_key',
347         'env_context' => false,
348         'key' => 'ekey',
349       },
350       # ...
351     },
352   },
353 )
354 ```
355
356 ### OAuth client ID and secret management by Chef Vault
357
358 - create vault items.
359
360 ```text
361 $ cat ~/tmp/concourse_oauth_client_id.json
362 {"cid":"***************************************************************"}
363 $ cat ~/tmp/concourse_oauth_client_secret.json
364 {"secret":"***************************************************************"}
365
366 $ knife vault create concourse web_oauth_client_id --json ~/tmp/concourse_oauth_client_id.json
367 $ knife vault create concourse web_oauth_client_secret --json ~/tmp/concourse_oauth_client_secret.json
368 ```
369
370 - grant reference permission to the Concourse host
371
372 ```text
373 $ knife vault update concourse web_oauth_client_id -S 'name:concourse-host.example.com'
374 $ knife vault update concourse web_oauth_client_secret -S 'name:concourse-host.example.com'
375 ```
376
377 - modify attributes
378
379 ```ruby
380 override_attributes(
381   'concourse-ci' => {
382     # ...
383     'docker-compose' => {
384       'web_oauth_client_id_vault_item' => {
385         'vault' => 'concourse',
386         'name' => 'web_oauth_client_id',
387         'env_context' => false,
388         'key' => 'cid',
389       },
390       'web_oauth_client_secret_vault_item' => {
391         'vault' => 'concourse',
392         'name' => 'web_oauth_client_secret',
393         'env_context' => false,
394         'key' => 'secret',
395       },
396       # ...
397     },
398   },
399 )
400 ```
401
402 ## License and Authors
403
404 - Author:: whitestar at osdn.jp
405
406 ```text
407 Copyright 2017, whitestar
408
409 Licensed under the Apache License, Version 2.0 (the "License");
410 you may not use this file except in compliance with the License.
411 You may obtain a copy of the License at
412
413     http://www.apache.org/licenses/LICENSE-2.0
414
415 Unless required by applicable law or agreed to in writing, software
416 distributed under the License is distributed on an "AS IS" BASIS,
417 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
418 See the License for the specific language governing permissions and
419 limitations under the License.
420 ```