Grid環境構築用のChefリポジトリです。
Revision | 90d9dc665fab7a989562fc9c576c8447e4601e21 (tree) |
---|---|
Time | 2017-09-03 16:24:37 |
Author | whitestar <whitestar@user...> |
Commiter | whitestar |
adds a reverse proxy service (Nginx) for the UI service SSL/TLS settings.
@@ -10,6 +10,8 @@ Lint/UnusedBlockArgument: | ||
10 | 10 | Enabled: false |
11 | 11 | Metrics/AbcSize: |
12 | 12 | Enabled: false |
13 | +Metrics/BlockNesting: | |
14 | + Max: 5 | |
13 | 15 | Style/PerlBackrefs: |
14 | 16 | Enabled: false |
15 | 17 | Security/Eval: |
@@ -38,20 +40,3 @@ Style/TrailingCommaInLiteral: | ||
38 | 40 | EnforcedStyleForMultiline: consistent_comma |
39 | 41 | Style/WordArray: |
40 | 42 | Enabled: false |
41 | - | |
42 | -#Lint/ShadowingOuterLocalVariable: | |
43 | -# Enabled: false | |
44 | -#Metrics/MethodLength: | |
45 | -# Max: 10 | |
46 | -#Metrics/ModuleLength: | |
47 | -# Max: 100 | |
48 | -#Metrics/CyclomaticComplexity: | |
49 | -# Max: 6 | |
50 | -#Metrics/PerceivedComplexity: | |
51 | -# Max: 7 | |
52 | -#Style/AccessorMethodName: | |
53 | -# Enabled: false | |
54 | -#Style/MultilineOperationIndentation: | |
55 | -# Enabled: false | |
56 | -#Style/PerlBackrefs: | |
57 | -# Enabled: false |
@@ -1,5 +1,10 @@ | ||
1 | 1 | # screwdriver CHANGELOG |
2 | 2 | |
3 | +0.2.0 | |
4 | +----- | |
5 | +- adds a reverse proxy service (Nginx) for the UI service SSL/TLS settings. | |
6 | +- bug fix. | |
7 | + | |
3 | 8 | 0.1.0 |
4 | 9 | ----- |
5 | 10 | - Initial release of screwdriver |
@@ -44,6 +44,7 @@ This cookbook sets up a Screwdriver CI/CD service by Docker Compose. | ||
44 | 44 | |`['screwdriver']['with_ssl_cert_cookbook']`|Boolean|See `attributes/default.rb`|`false`| |
45 | 45 | |`['screwdriver']['ssl_cert']['ca_names']`|Array|Internal CA names that are imported by the ssl_cert cookbook.|`[]`| |
46 | 46 | |`['screwdriver']['ssl_cert']['common_name']`|String|Server common name for TLS|`node['fqdn']`| |
47 | +|`['screwdriver']['ui']['tls_setup_mode']`|String|`'reverseproxy'` only. Note: [_Add TLS support to UI docker container #377_](https://github.com/screwdriver-cd/screwdriver/issues/377)|`'reverseproxy'`| | |
47 | 48 | |`['screwdriver']['api']['config']`|Hash|This hash object is expanded to a `/config/local.yaml` file in the API Docker container.|See `attributes/default.rb`| |
48 | 49 | |`['screwdriver']['store']['config']`|Hash|This hash object is expanded to a `/config/local.yaml` file in the Store Docker container.|See `attributes/default.rb`| |
49 | 50 | |`['screwdriver']['docker-compose']['import_ca']`|Boolean|whether import internal CA certificates or not.|`false`| |
@@ -51,6 +52,7 @@ This cookbook sets up a Screwdriver CI/CD service by Docker Compose. | ||
51 | 52 | |`['screwdriver']['docker-compose']['bin_dir']`|String|Path string.|`"#{node['screwdriver']['docker-compose']['app_dir']}/bin"`| |
52 | 53 | |`['screwdriver']['docker-compose']['config_dir']`|String|Path string.|`"#{node['screwdriver']['docker-compose']['app_dir']}/config"`| |
53 | 54 | |`['screwdriver']['docker-compose']['data_dir']`|String|Path string.|`"#{node['screwdriver']['docker-compose']['app_dir']}/data"`| |
55 | +|`['screwdriver']['docker-compose']['etc_dir']`|String|Path string.|`"#{node['screwdriver']['docker-compose']['app_dir']}/etc"`| | |
54 | 56 | |`['screwdriver']['docker-compose']['jwt_private_key_reset']`|Boolean|Only available if the JWT key pair is automatically generated by Chef.|`false`| |
55 | 57 | |`['screwdriver']['docker-compose']['jwt_private_key_vault_item']`|Hash|Optional, Sets a JWT private key from Chef Vault. See `attributes/default.rb`|`{}`| |
56 | 58 | |`['screwdriver']['docker-compose']['jwt_public_key_vault_item']`|Hash|Optional, Sets a JWT public key from Chef Vault. See `attributes/default.rb`|`{}`| |
@@ -156,6 +158,104 @@ override_attributes( | ||
156 | 158 | ) |
157 | 159 | ``` |
158 | 160 | |
161 | +- `roles/screwdriver-with-ssl.rb` | |
162 | + | |
163 | +```ruby | |
164 | +name 'screwdriver-with-ssl' | |
165 | +description 'screwdriver with SSL' | |
166 | + | |
167 | +cn = 'screwdriver.io.example.com' | |
168 | +ui_port = '9000' | |
169 | +api_port = '9001' | |
170 | +store_port = '9002' | |
171 | + | |
172 | +run_list( | |
173 | + 'role[docker]', | |
174 | + 'recipe[screwdriver::docker-compose]', | |
175 | +) | |
176 | + | |
177 | +override_attributes( | |
178 | + 'ssl_cert' => { | |
179 | + 'common_names' => [ | |
180 | + cn, | |
181 | + ], | |
182 | + }, | |
183 | + 'screwdriver' => { | |
184 | + 'with_ssl_cert_cookbook' => true, | |
185 | + 'ssl_cert' => { | |
186 | + 'common_name' => cn, | |
187 | + }, | |
188 | + 'docker-compose' => { | |
189 | + 'oauth_client_id_vault_item' => { | |
190 | + 'vault' => 'screwdriver', | |
191 | + 'name' => 'oauth_client_id', | |
192 | + 'env_context' => false, | |
193 | + 'key' => 'cid', # real hash path: "/cid" | |
194 | + }, | |
195 | + 'oauth_client_secret_vault_item' => { | |
196 | + 'vault' => 'screwdriver', | |
197 | + 'name' => 'oauth_client_secret', | |
198 | + 'env_context' => false, | |
199 | + 'key' => 'secret', # real hash path: "/secret" | |
200 | + }, | |
201 | + 'config' => { | |
202 | + 'services' => { | |
203 | + 'reverseproxy' => { | |
204 | + 'ports' => [ | |
205 | + "#{ui_port}:9000", | |
206 | + ], | |
207 | + 'environment' => { | |
208 | + }, | |
209 | + }, | |
210 | + 'api' => { | |
211 | + 'ports' => [ | |
212 | + "#{api_port}:80", | |
213 | + ], | |
214 | + 'environment' => { | |
215 | + 'SCM_PLUGIN' => 'gitlab', # 'gitlab' or 'github' or 'bitbucket' | |
216 | + # OAuth Callback URL: "http://#{node['fqdn']}:9001/v4/auth/login/web" | |
217 | + 'SCM_USERNAME' => 'ci-tool', | |
218 | + 'SCM_EMAIL' => 'citool@mail.example.com', | |
219 | + #'WEBHOOK_GITHUB_SECRET' => 'SUPER-SECRET-SIGNING-THING', | |
220 | + 'SCM_GITLAB_HOST' => 'gitlab.io.example.com', | |
221 | + 'SCM_GITLAB_PROTOCOL' => 'https', | |
222 | + 'NODE_TLS_REJECT_UNAUTHORIZED' => '0', # for self-signed cetificates | |
223 | + # The following variables will be set by the screwdriver::docker-compose recipe automatically. | |
224 | + #'SECRET_OAUTH_CLIENT_ID' => '${SECRET_OAUTH_CLIENT_ID}', | |
225 | + #'SECRET_OAUTH_CLIENT_SECRET' => '${SECRET_OAUTH_CLIENT_SECRET}', | |
226 | + #'SECRET_JWT_PRIVATE_KEY' => '${SECRET_JWT_PRIVATE_KEY}', | |
227 | + #'SECRET_JWT_PUBLIC_KEY' => '${SECRET_JWT_PUBLIC_KEY}', | |
228 | + #'ECOSYSTEM_UI' => "http://#{node['fqdn']}:#{ui_port}", | |
229 | + #'ECOSYSTEM_STORE' => "http://#{node['fqdn']}:#{store_port}", | |
230 | + }, | |
231 | + }, | |
232 | + 'ui' => { | |
233 | + #'ports' => [ | |
234 | + # "#{ui_port}:80", | |
235 | + #], | |
236 | + 'environment' => { | |
237 | + # These variables will be set by the screwdriver::docker-compose recipe automatically. | |
238 | + #'ECOSYSTEM_API' => "http://#{node['fqdn']}:#{api_port}", | |
239 | + #'ECOSYSTEM_STORE' => "http://#{node['fqdn']}:#{store_port}", | |
240 | + }, | |
241 | + }, | |
242 | + 'store' => { | |
243 | + 'ports' => [ | |
244 | + "#{store_port}:80", | |
245 | + ], | |
246 | + 'environment' => { | |
247 | + # These variables will be set by the screwdriver::docker-compose recipe automatically. | |
248 | + #'ECOSYSTEM_UI' => "http://#{node['fqdn']}:#{ui_port}", | |
249 | + #'SECRET_JWT_PUBLIC_KEY' => '${SECRET_JWT_PUBLIC_KEY}', | |
250 | + }, | |
251 | + }, | |
252 | + }, | |
253 | + }, | |
254 | + }, | |
255 | + }, | |
256 | +) | |
257 | +``` | |
258 | + | |
159 | 259 | ### SSL server keys and certificates management by ssl_cert cookbook |
160 | 260 | |
161 | 261 | - create vault items. |
@@ -25,6 +25,7 @@ default['screwdriver']['ssl_cert']['ca_names'] = [] | ||
25 | 25 | default['screwdriver']['ssl_cert']['common_name'] = node['fqdn'] |
26 | 26 | cn = node['screwdriver']['ssl_cert']['common_name'] |
27 | 27 | |
28 | +force_override['screwdriver']['ui']['tls_setup_mode'] = 'reverseproxy' | |
28 | 29 | # These hash objects are expanded to a `/config/local.yaml` file in each Docker container. |
29 | 30 | default['screwdriver']['api']['config'] = { |
30 | 31 | 'auth' => {}, |
@@ -45,6 +46,7 @@ default['screwdriver']['docker-compose']['app_dir'] = "#{node['docker-grid']['co | ||
45 | 46 | default['screwdriver']['docker-compose']['bin_dir'] = "#{node['screwdriver']['docker-compose']['app_dir']}/bin" |
46 | 47 | default['screwdriver']['docker-compose']['config_dir'] = "#{node['screwdriver']['docker-compose']['app_dir']}/config" |
47 | 48 | default['screwdriver']['docker-compose']['data_dir'] = "#{node['screwdriver']['docker-compose']['app_dir']}/data" |
49 | +default['screwdriver']['docker-compose']['etc_dir'] = "#{node['screwdriver']['docker-compose']['app_dir']}/etc" | |
48 | 50 | default['screwdriver']['docker-compose']['jwt_private_key_reset'] = false |
49 | 51 | default['screwdriver']['docker-compose']['jwt_private_key_vault_item'] = { |
50 | 52 | =begin |
@@ -139,6 +141,24 @@ version_2_config = { | ||
139 | 141 | # Version 2 docker-compose format |
140 | 142 | 'version' => '2', |
141 | 143 | 'services' => { |
144 | + # this service will be active if the `['screwdriver']['with_ssl_cert_cookbook']` attribute is true. | |
145 | + 'reverseproxy' => { | |
146 | + 'depends_on' => [ | |
147 | + 'ui', | |
148 | + ], | |
149 | + 'restart' => 'always', | |
150 | + 'image' => 'nginx:alpine', | |
151 | + 'expose' => [ | |
152 | + '9000', | |
153 | + ], | |
154 | + 'ports' => [ | |
155 | + #'9000:9000', # default | |
156 | + ], | |
157 | + 'volumes' => [ | |
158 | + # This volume will be set by the screwdriver::docker-compose recipe automatically. | |
159 | + #"#{node['screwdriver']['docker-compose']['etc_dir']}/nginx/nginx.conf:/etc/nginx/nginx.conf:ro", | |
160 | + ], | |
161 | + }, | |
142 | 162 | 'api' => { |
143 | 163 | 'image' => 'screwdrivercd/screwdriver:stable', |
144 | 164 | 'command' => 'npm start', # the original command in the Dockerfile. |
@@ -26,12 +26,14 @@ app_dir = node['screwdriver']['docker-compose']['app_dir'] | ||
26 | 26 | bin_dir = node['screwdriver']['docker-compose']['bin_dir'] |
27 | 27 | config_dir = node['screwdriver']['docker-compose']['config_dir'] |
28 | 28 | data_dir = node['screwdriver']['docker-compose']['data_dir'] |
29 | +etc_dir = node['screwdriver']['docker-compose']['etc_dir'] | |
29 | 30 | |
30 | 31 | [ |
31 | 32 | app_dir, |
32 | 33 | bin_dir, |
33 | 34 | config_dir, |
34 | 35 | data_dir, |
36 | + "#{etc_dir}/nginx", | |
35 | 37 | ].each {|dir| |
36 | 38 | resources(directory: dir) rescue directory dir do |
37 | 39 | owner 'root' |
@@ -192,7 +194,7 @@ if ports.empty? | ||
192 | 194 | else |
193 | 195 | ports.each {|port| |
194 | 196 | elms = port.split(':') |
195 | - api_port = (elms.size == 2 ? elms[0] : elms[1]) if elms.last == ui_in_port | |
197 | + ui_port = (elms.size == 2 ? elms[0] : elms[1]) if elms.last == ui_in_port | |
196 | 198 | } |
197 | 199 | end |
198 | 200 |
@@ -209,7 +211,7 @@ if ports.empty? | ||
209 | 211 | else |
210 | 212 | ports.each {|port| |
211 | 213 | elms = port.split(':') |
212 | - api_port = (elms.size == 2 ? elms[0] : elms[1]) if elms.last == store_in_port | |
214 | + store_port = (elms.size == 2 ? elms[0] : elms[1]) if elms.last == store_in_port | |
213 | 215 | } |
214 | 216 | end |
215 | 217 |
@@ -234,15 +236,54 @@ if node['screwdriver']['with_ssl_cert_cookbook'] | ||
234 | 236 | api_uri = api_uri.gsub('http://', 'https://') |
235 | 237 | store_uri = store_uri.gsub('http://', 'https://') |
236 | 238 | |
239 | + override_api_config['httpd']['tls'] = {} # for FalseClass by default. | |
237 | 240 | override_api_config['httpd']['tls']['cert'] = server_cert |
238 | 241 | override_api_config['httpd']['tls']['key'] = server_key |
239 | 242 | api_envs['IS_HTTPS'] = 'true' |
240 | 243 | |
244 | + override_store_config['httpd']['tls'] = {} # for FalseClass by default. | |
241 | 245 | override_store_config['httpd']['tls']['cert'] = server_cert |
242 | 246 | override_store_config['httpd']['tls']['key'] = server_key |
243 | 247 | |
244 | 248 | # Note: Screwdriver UI image does not support TLS settings yet. |
245 | 249 | # https://github.com/screwdriver-cd/screwdriver/issues/377 |
250 | + | |
251 | + if node['screwdriver']['ui']['tls_setup_mode'] == 'reverseproxy' | |
252 | + rproxy_in_port = '9000' | |
253 | + ports = config_srvs['reverseproxy']['ports'] | |
254 | + if ports.empty? | |
255 | + override_config_srvs['reverseproxy']['ports'] = ["#{ui_port}:#{rproxy_in_port}"] | |
256 | + else | |
257 | + ports.each {|port| | |
258 | + elms = port.split(':') | |
259 | + ui_port = (elms.size == 2 ? elms[0] : elms[1]) if elms.last == rproxy_in_port | |
260 | + } | |
261 | + end | |
262 | + ui_uri = api_uri.gsub(/:\d+/, ":#{ui_port}") # based on the API URI. | |
263 | + # do not expose UI service directly. | |
264 | + node.rm('screwdriver', 'docker-compose', 'config', 'services', 'ui', 'ports') | |
265 | + | |
266 | + rproxy_vols = config_srvs['reverseproxy']['volumes'].to_a | |
267 | + rproxy_vols.push("#{etc_dir}/nginx/nginx.conf:/etc/nginx/nginx.conf:ro") | |
268 | + # Nginx parent process owner is root. | |
269 | + rproxy_vols.push("#{server_cert_path(cn)}:/root/server.crt:ro") | |
270 | + rproxy_vols.push("#{server_key_path(cn)}:/root/server.key:ro") | |
271 | + # reset vlumes array. | |
272 | + override_config_srvs['reverseproxy']['volumes'] = rproxy_vols | |
273 | + | |
274 | + template "#{etc_dir}/nginx/nginx.conf" do | |
275 | + source 'opt/docker-compose/app/screwdriver/etc/nginx/nginx.conf' | |
276 | + owner 'root' | |
277 | + group 'root' | |
278 | + mode '0644' | |
279 | + action :create | |
280 | + end | |
281 | + else | |
282 | + node.rm('screwdriver', 'docker-compose', 'config', 'services', 'reverseproxy') | |
283 | + # TODO: in the future. | |
284 | + end | |
285 | +else | |
286 | + node.rm('screwdriver', 'docker-compose', 'config', 'services', 'reverseproxy') | |
246 | 287 | end |
247 | 288 | |
248 | 289 | # normalize URIs |
@@ -0,0 +1,39 @@ | ||
1 | +<% | |
2 | +ssl_enabled = node['screwdriver']['with_ssl_cert_cookbook'] | |
3 | +-%> | |
4 | +worker_processes 1; | |
5 | + | |
6 | +events { | |
7 | + worker_connections 1024; | |
8 | +} | |
9 | + | |
10 | +http { | |
11 | + sendfile on; | |
12 | + | |
13 | + upstream docker-ui { | |
14 | + server ui:80; | |
15 | + } | |
16 | + | |
17 | + server { | |
18 | +<% if ssl_enabled %> | |
19 | + listen 9000 default ssl; | |
20 | + ssl on; | |
21 | + ssl_certificate /root/server.crt; | |
22 | + ssl_certificate_key /root/server.key; | |
23 | +<% else %> | |
24 | + listen 9000; | |
25 | +<% end %> | |
26 | + | |
27 | + location / { | |
28 | + proxy_pass http://docker-ui/; | |
29 | + proxy_redirect off; | |
30 | + proxy_set_header Host $http_host; # $host does not include the port number. | |
31 | + proxy_set_header X-Real-IP $remote_addr; | |
32 | +<% if ssl_enabled %> | |
33 | + proxy_set_header X-Forwarded-Proto https; | |
34 | +<% end %> | |
35 | + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | |
36 | + proxy_set_header X-Forwarded-Host $server_name; | |
37 | + } | |
38 | + } | |
39 | +} |
@@ -1 +1 @@ | ||
1 | -0.1.0 | |
1 | +0.2.0 |