OSDN Git Service

adds SSL configurations. concourse-ci-0.1.1
authorwhitestar <whitestar@gaea.test>
Sun, 12 Feb 2017 05:52:04 +0000 (14:52 +0900)
committerwhitestar <whitestar@gaea.test>
Sun, 12 Feb 2017 05:52:04 +0000 (14:52 +0900)
cookbooks/concourse-ci/Berksfile [new file with mode: 0644]
cookbooks/concourse-ci/CHANGELOG.md
cookbooks/concourse-ci/README.md
cookbooks/concourse-ci/attributes/default.rb
cookbooks/concourse-ci/metadata.rb
cookbooks/concourse-ci/recipes/docker-compose.rb
cookbooks/concourse-ci/templates/default/opt/docker-compose/app/concourse/docker-compose.yml
roles/concourse.rb

diff --git a/cookbooks/concourse-ci/Berksfile b/cookbooks/concourse-ci/Berksfile
new file mode 100644 (file)
index 0000000..7e6ac6c
--- /dev/null
@@ -0,0 +1,21 @@
+#
+# Copyright 2017 whitestar
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# for ver. 3.x
+#source 'https://gpm00.grid.example.com:6280'
+source 'https://supermarket.chef.io'
+
+metadata
index 2701beb..06e1f9a 100644 (file)
@@ -1,6 +1,13 @@
 concourse-ci CHANGELOG
 ======================
 
+0.1.1
+-----
+- adds SSL configurations.
+- improves passwords management.
+- adds the `['concourse-ci']['docker-compose']['(db|web)_password_reset']` attributes.
+- adds the `['concourse-ci']['docker-compose']['ssh_keys_reset']` attribute.
+
 0.1.0
 -----
 - Initial release of concourse-ci
index 9aecbe5..b9967c1 100644 (file)
@@ -15,6 +15,7 @@ This cookbook sets up a Concourse CI service by Docker Compose.
         - [concourse-ci::default](#concourse-cidefault)
         - [concourse-ci::docker-compose](#concourse-cidocker-compose)
     - [Role Examples](#role-examples)
+    - [SSL server keys and certificates management by ssl_cert cookbook](#ssl-server-keys-and-certificates-management-by-ssl_cert-cookbook)
 - [License and Authors](#license-and-authors)
 
 ## Requirements
@@ -37,7 +38,12 @@ This cookbook sets up a Concourse CI service by Docker Compose.
 |`['concourse-ci']['docker-compose']['pgdata_dir']`|String|Path string or nil (unset).|`"#{node['concourse-ci']['docker-compose']['app_dir']}/database"`|
 |`['concourse-ci']['docker-compose']['web_keys_dir']`|String|Path string.|`"#{node['concourse-ci']['docker-compose']['app_dir']}/keys/web"`|
 |`['concourse-ci']['docker-compose']['worker_keys_dir']`|String|Path string.|`"#{node['concourse-ci']['docker-compose']['app_dir']}/keys/worker"`|
-|`['concourse-ci']['docker-compose']['pgdata_dir']`|String|Path string or nil (unset).|`"#{node['concourse-ci']['docker-compose']['app_dir']}/database"`|
+|`['concourse-ci']['docker-compose']['pgdata_dir']`|String|Path string or nil (unset, non-persistent).|`"#{node['concourse-ci']['docker-compose']['app_dir']}/database"`|
+|`['concourse-ci']['docker-compose']['db_password_reset']`|String|Only available if the password is automatically generated by Chef.|`false`|
+|`['concourse-ci']['docker-compose']['db_password_vault_item']`|Hash|See `attributes/default.rb`|`{}`|
+|`['concourse-ci']['docker-compose']['web_password_reset']`|String|Only available if the password is automatically generated by Chef.|`false`|
+|`['concourse-ci']['docker-compose']['web_password_vault_item']`|Hash|See `attributes/default.rb`|`{}`|
+|`['concourse-ci']['docker-compose']['ssh_keys_reset']`|String|Resets all SSH keys forcely.|`false`|
 |`['concourse-ci']['docker-compose']['config_format_version']`|String|Read only. `docker-compose.yml` format version. Only version 1 is supported now.|`'1'`|
 |`['concourse-ci']['docker-compose']['config']`|Hash|`docker-compose.yml` configurations.|See `attributes/default.rb`|
 
@@ -92,6 +98,112 @@ override_attributes(
 )
 ```
 
+- `roles/concourse-with-ssl.rb`
+
+```ruby
+name 'concourse-with-ssl'
+description 'Concourse with SSL'
+
+run_list(
+  'recipe[ssl_cert::server_key_pairs]',
+  'role[docker]',
+  'recipe[concourse-ci::docker-compose]',
+)
+
+image = 'concourse/concourse:2.6.0'
+port = '18443'
+cn = 'concourse.io.example.com'
+
+override_attributes(
+  'ssl_cert' => {
+    'common_names' => [
+      cn,
+    ],
+  },
+  'concourse-ci' => {
+    'with_ssl_cert_cookbook' => true,
+    'ssl_cert' => {
+      'common_name' => cn,
+    },
+    'docker-compose' => {
+      'config' => {
+        # Version 1 docker-compose format
+        'concourse-web' => {
+          'image' => image,
+          'ports' => [
+            "#{port}:8443",
+          ],
+          'environment' => {
+            'CONCOURSE_EXTERNAL_URL' => "https://192.168.1.3:#{port}",
+            'CONCOURSE_TLS_BIND_PORT' => '8443',  # activate HTTPS
+            # These environments will be set by the concourse-ci::docker-compose recipe automatically.
+            #'CONCOURSE_TLS_CERT' => '/root/server.crt',
+            #'CONCOURSE_TLS_KEY' => '/root/server.key',
+          },
+          'volumes' => [
+            # These volumes will be set by the concourse-ci::docker-compose recipe automatically.
+            #"#{server_cert_path(node['concourse-ci']['ssl_cert']['common_name'])}:/root/server.crt:ro",
+            #"#{server_key_path(node['concourse-ci']['ssl_cert']['common_name'])}:/root/server.key:ro",
+          ],
+        },
+        'concourse-worker' => {
+          'image' => image,
+        },
+      },
+    },
+  },
+)
+```
+
+### SSL server keys and certificates management by ssl_cert cookbook
+
+- create vault items.
+
+```text
+$ ruby -rjson -e 'puts JSON.generate({"private" => File.read("concourse_io_example_com.prod.key")})' \
+> > ~/tmp/concourse_io_example_com.prod.key.json
+
+$ knife vault create ssl_server_keys concourse.io.example.com.prod \
+> --json ~/tmp/concourse_io_example_com.prod.key.json
+
+$ ruby -rjson -e 'puts JSON.generate({"public" => File.read("concourse_io_example_com.prod.crt")})' \
+> > ~/tmp/concourse_io_example_com.prod.crt.json
+
+$ knife vault create ssl_server_certs concourse.io.example.com.prod \
+> --json ~/tmp/concourse_io_example_com.prod.crt.json
+```
+
+- grant reference permission to the Concourse host
+
+```text
+$ knife vault update ssl_server_keys  concourse.io.example.com.prod -S 'name:concourse-host.example.com'
+$ knife vault update ssl_server_certs concourse.io.example.com.prod -S 'name:concourse-host.example.com'
+```
+
+- modify run_list and attributes
+
+```ruby
+run_list(
+  'recipe[ssl_cert::server_key_pairs]',
+  'recipe[concourse-ci::docker-compose]',
+)
+
+override_attributes(
+  'ssl_cert' => {
+    'common_names' => [
+      'concourse.io.example.com',
+    ],
+  },
+  'concourse-ci' => {
+    'with_ssl_cert_cookbook' => true,
+    'ssl_cert' => {
+      'common_name' => 'concourse.io.example.com',
+    },
+    # ...
+  },
+)
+```
+
 ## License and Authors
 
 - Author:: whitestar at osdn.jp
index 864bb09..f6f17e1 100644 (file)
@@ -17,8 +17,7 @@
 # limitations under the License.
 #
 
-# TODO: support with_ssl_cert_cookbook
-force_override['concourse-ci']['with_ssl_cert_cookbook'] = false
+default['concourse-ci']['with_ssl_cert_cookbook'] = false
 # If ['concourse-ci']['with_ssl_cert_cookbook'] is true,
 # node['concourse-ci']['docker-compose']['config']
 # are overridden by the following 'common_name' attributes.
@@ -27,6 +26,33 @@ default['concourse-ci']['docker-compose']['app_dir'] = "#{node['docker-grid']['c
 default['concourse-ci']['docker-compose']['pgdata_dir'] = "#{node['concourse-ci']['docker-compose']['app_dir']}/database"
 default['concourse-ci']['docker-compose']['web_keys_dir'] = "#{node['concourse-ci']['docker-compose']['app_dir']}/keys/web"
 default['concourse-ci']['docker-compose']['worker_keys_dir'] = "#{node['concourse-ci']['docker-compose']['app_dir']}/keys/worker"
+default['concourse-ci']['docker-compose']['db_password_reset'] = false
+default['concourse-ci']['docker-compose']['db_password_vault_item'] = {
+=begin
+  'vault' => 'concourse',
+  'name' => 'db_password',
+  # single password or nested hash password path delimited by slash
+  'env_context' => false,
+  'key' => 'password',  # real hash path: "/password"
+  # or nested hash password path delimited by slash
+  #'env_context' => true,
+  #'key' => 'hash/path/to/password',  # real hash path: "/#{node.chef_environment}/hash/path/to/password"
+=end
+}
+default['concourse-ci']['docker-compose']['web_password_reset'] = false
+default['concourse-ci']['docker-compose']['web_password_vault_item'] = {
+=begin
+  'vault' => 'concourse',
+  'name' => 'web_password',
+  # single password or nested hash password path delimited by slash
+  'env_context' => false,
+  'key' => 'password',  # real hash path: "/password"
+  # or nested hash password path delimited by slash
+  #'env_context' => true,
+  #'key' => 'hash/path/to/password',  # real hash path: "/#{node.chef_environment}/hash/path/to/password"
+=end
+}
+default['concourse-ci']['docker-compose']['ssh_keys_reset'] = false
 
 # TODO: support version 2 format, and use `default` instead of `force_override`
 force_override['concourse-ci']['docker-compose']['config_format_version'] = '1'
@@ -40,6 +66,7 @@ version_1_config = {
     'environment' => {
       'POSTGRES_DB' => 'concourse',
       'POSTGRES_USER' => 'concourse',
+      # Note: You should use the `['concourse-ci']['docker-compose']['db_password_vault_item']` attribute.
       'POSTGRES_PASSWORD' => nil,
       'PGDATA' => '/database',
     },
@@ -53,12 +80,15 @@ version_1_config = {
     'command' => 'web',
     'ports' => [
       #'8080:8080',  # If you sepecify no value, Chef will sets '8080:8080'.
+      #'8443:8443',  # https
     ],
     'volumes' => [
       "#{node['concourse-ci']['docker-compose']['web_keys_dir']}:/concourse-keys",
     ],
     'environment' => {
+      #'CONCOURSE_TLS_BIND_PORT' => '8443',  # activate HTTPS
       'CONCOURSE_BASIC_AUTH_USERNAME' => 'concourse',
+      # Note: You should use the `['concourse-ci']['docker-compose']['web_password_vault_item']` attribute.
       'CONCOURSE_BASIC_AUTH_PASSWORD' => nil,
       # If you sepecify no value, Chef will sets "http://#{node['ipaddress']}:8080".
       'CONCOURSE_EXTERNAL_URL' => nil,
index 0d330ae..ed910e3 100644 (file)
@@ -5,9 +5,9 @@ maintainer_email ''
 license          'Apache 2.0'
 description      'Installs/Configures Concourse CI by Docker Compose'
 long_description IO.read(File.join(File.dirname(__FILE__), 'README.md'))
-version          '0.1.0'
+version          '0.1.1'
 source_url       'http://scm.osdn.jp/gitroot/metasearch/grid-chef-repo.git'
 issues_url       'https://osdn.jp/projects/metasearch/ticket'
 
 depends 'docker-grid', '>= 0.2.7'
-depends 'ssl_cert', '>= 0.3.3'
+depends 'ssl_cert', '>= 0.3.7'
index 52929cd..a777e26 100644 (file)
@@ -17,6 +17,8 @@
 # limitations under the License.
 #
 
+::Chef::Recipe.send(:include, SSLCert::Helper)
+
 require 'securerandom'
 
 doc_url = 'https://concourse.ci/docker-repository.html'
@@ -27,36 +29,52 @@ app_dir = node['concourse-ci']['docker-compose']['app_dir']
 pgdata_dir = node['concourse-ci']['docker-compose']['pgdata_dir']
 web_keys_dir = node['concourse-ci']['docker-compose']['web_keys_dir']
 worker_keys_dir = node['concourse-ci']['docker-compose']['worker_keys_dir']
-#certs_dir = "#{app_dir}/certs"
 
 [
   app_dir,
-  pgdata_dir,
   web_keys_dir,
   worker_keys_dir,
-  #certs_dir,
 ].each {|dir|
   resources(directory: dir) rescue directory dir do
     owner 'root'
     group 'root'
     mode '0755'
     recursive true
-  end if !dir.nil? && !dir.empty?
+  end
 }
 
+# DB persistent
+resources(directory: pgdata_dir) rescue directory pgdata_dir do
+  #owner 999
+  group 'root'
+  mode '0700'
+  recursive true
+end if !pgdata_dir.nil? && !pgdata_dir.empty?
+
 bash 'ssh-keygen_keys' do
   code <<-"EOH"
-  script commands
+    rm -f #{web_keys_dir}/*
     ssh-keygen -t rsa -f #{web_keys_dir}/tsa_host_key -N ''
     ssh-keygen -t rsa -f #{web_keys_dir}/session_signing_key -N ''
+    rm -f #{worker_keys_dir}/*
     ssh-keygen -t rsa -f #{worker_keys_dir}/worker_key -N ''
     cp #{worker_keys_dir}/worker_key.pub #{web_keys_dir}/authorized_worker_keys
     cp #{web_keys_dir}/tsa_host_key.pub #{worker_keys_dir}
   EOH
   action :run
-  not_if { File.exist?("#{web_keys_dir}/tsa_host_key") }
-  not_if { File.exist?("#{web_keys_dir}/session_signing_key") }
-  not_if { File.exist?("#{worker_keys_dir}/worker_key") }
+  unless node['concourse-ci']['docker-compose']['ssh_keys_reset']
+    not_if { File.exist?("#{web_keys_dir}/tsa_host_key") }
+    not_if { File.exist?("#{web_keys_dir}/session_signing_key") }
+    not_if { File.exist?("#{worker_keys_dir}/worker_key") }
+  end
+end
+
+config_file = "#{app_dir}/docker-compose.yml"
+config_srvs_local = nil
+if File.exist?(config_file)
+  require 'yaml'
+  config_srvs_local = YAML.load_file(config_file)
+  config_srvs_local = config_srvs_local['services'] if config_srvs_local.key?('version') && config_srvs_local['version'] == '2'
 end
 
 config_format_version = node['concourse-ci']['docker-compose']['config_format_version']
@@ -74,67 +92,102 @@ end
 # Database
 db_envs_org = config_srvs['concourse-db']['environment']
 db_envs = {}
-db_vols = []
-
-db_passwd = db_envs_org['POSTGRES_PASSWORD']
-if db_passwd.nil? || db_passwd.empty?
-  db_passwd = SecureRandom.hex  # or urlsafe_base64
-  db_envs['POSTGRES_PASSWORD'] = db_passwd
+db_vols = config_srvs['concourse-db']['volumes'].to_a
+
+db_passwd = nil
+db_password_vault_item = node['concourse-ci']['docker-compose']['db_password_vault_item']
+if !db_password_vault_item.empty?
+  # 1.
+  db_passwd = get_vault_item_value(db_password_vault_item)
+else
+  # 2.
+  db_passwd = db_envs_org['POSTGRES_PASSWORD']
+  if db_passwd.nil? || db_passwd.empty?
+    db_passwd = \
+      if !config_srvs_local.nil? && !node['concourse-ci']['docker-compose']['db_password_reset']
+        # 3.
+        config_srvs_local['concourse-db']['environment']['POSTGRES_PASSWORD']
+      else
+        # 4.
+        SecureRandom.hex  # or urlsafe_base64
+      end
+  end
 end
+# prevent Chef from logging password attribute value. (=> template variables)
+#db_envs['POSTGRES_PASSWORD'] = db_passwd
 
 db_vols.push("#{pgdata_dir}:#{db_envs_org['PGDATA']}") if !pgdata_dir.nil? && !pgdata_dir.empty?
 
+# merge environment hash
 force_override_config_srvs['concourse-db']['environment'] = db_envs unless db_envs.empty?
+# reset vlumes array.
 override_config_srvs['concourse-db']['volumes'] = db_vols unless db_vols.empty?
 
 # Web
 web_envs_org = config_srvs['concourse-web']['environment']
 web_envs = {}
+web_vols = config_srvs['concourse-web']['volumes'].to_a
 
 web_ports = config_srvs['concourse-web']['ports']
 override_config_srvs['concourse-web']['ports'] = ['8080:8080'] if web_ports.empty?
 
-basic_auth_passwd = web_envs_org['CONCOURSE_BASIC_AUTH_PASSWORD']
-if basic_auth_passwd.nil? || basic_auth_passwd.empty?
-  basic_auth_passwd = SecureRandom.hex  # or urlsafe_base64
-  web_envs['CONCOURSE_BASIC_AUTH_PASSWORD'] = basic_auth_passwd
+basic_auth_passwd = nil
+web_password_vault_item = node['concourse-ci']['docker-compose']['web_password_vault_item']
+if !web_password_vault_item.empty?
+  # 1.
+  basic_auth_passwd = get_vault_item_value(web_password_vault_item)
+else
+  # 2.
+  basic_auth_passwd = web_envs_org['CONCOURSE_BASIC_AUTH_PASSWORD']
+  if basic_auth_passwd.nil? || basic_auth_passwd.empty?
+    basic_auth_passwd = \
+      if !config_srvs_local.nil? && !node['concourse-ci']['docker-compose']['web_password_reset']
+        # 3.
+        config_srvs_local['concourse-web']['environment']['CONCOURSE_BASIC_AUTH_PASSWORD']
+      else
+        # 4.
+        SecureRandom.hex  # or urlsafe_base64
+      end
+  end
 end
+# prevent Chef from logging password attribute value. (=> template variables)
+#web_envs['CONCOURSE_BASIC_AUTH_PASSWORD'] = basic_auth_passwd
 
 external_url = web_envs_org['CONCOURSE_EXTERNAL_URL']
 web_envs['CONCOURSE_EXTERNAL_URL'] = "http://#{node['ipaddress']}:8080" if external_url.nil?
 
 data_source = web_envs_org['CONCOURSE_POSTGRES_DATA_SOURCE']
-data_source.gsub!(/<POSTGRES_PASSWORD>/, db_passwd)
-web_envs['CONCOURSE_POSTGRES_DATA_SOURCE'] = data_source
-
-force_override_config_srvs['concourse-web']['environment'] = web_envs unless web_envs.empty?
+data_source = data_source.gsub(/<POSTGRES_PASSWORD>/, db_passwd)
+# prevent Chef from logging password attribute value. (=> template variables)
+#web_envs['CONCOURSE_POSTGRES_DATA_SOURCE'] = data_source
 
-=begin
 if node['concourse-ci']['with_ssl_cert_cookbook']
   ::Chef::Recipe.send(:include, SSLCert::Helper)
   cn = node['concourse-ci']['ssl_cert']['common_name']
-  key_path = server_key_path(cn)
-
-  bash 'copy_ssl_server_key' do
-    code <<-EOH
-      cp #{key_path} #{certs_dir}/server.key
-      chmod 600 #{certs_dir}/server.key
-    EOH
-    sensitive true
-    action :nothing
-    subscribes :run, "file[#{key_path}]"
-  end
-
-  # TODO: key path setup.
+  # Concourse web process owner is root.
+  web_vols.push("#{server_cert_path(cn)}:/root/server.crt:ro")
+  web_vols.push("#{server_key_path(cn)}:/root/server.key:ro")
+  web_envs['CONCOURSE_TLS_CERT'] = '/root/server.crt'
+  web_envs['CONCOURSE_TLS_KEY'] = '/root/server.key'
 end
-=end
 
-template "#{app_dir}/docker-compose.yml" do
+# merge environment hash
+force_override_config_srvs['concourse-web']['environment'] = web_envs unless web_envs.empty?
+# reset vlumes array.
+override_config_srvs['concourse-web']['volumes'] = web_vols unless web_vols.empty?
+
+template config_file do
   source  'opt/docker-compose/app/concourse/docker-compose.yml'
   owner 'root'
   group 'root'
   mode '0600'
   sensitive true
+  # prevent Chef from logging password attribute value.
+  variables(
+    db_passwd: db_passwd,
+    basic_auth_passwd: basic_auth_passwd,
+    data_source: data_source
+  )
 end
 
 log <<-"EOM"
index 0e5de26..240a87a 100644 (file)
@@ -1,7 +1,20 @@
 <%
-config = node['concourse-ci']['docker-compose']['config']
+config_format_version = node['concourse-ci']['docker-compose']['config_format_version']
+config = node['concourse-ci']['docker-compose']['config'].to_hash
+
+config_srvs = \
+  if config_format_version == '1'
+    config
+  elsif config_format_version == '2'
+    config['services']
+  end
+
+# prevent Chef from logging password attribute value.
+config_srvs['concourse-db']['environment']['POSTGRES_PASSWORD'] = @db_passwd
+config_srvs['concourse-web']['environment']['CONCOURSE_BASIC_AUTH_PASSWORD'] = @basic_auth_passwd
+config_srvs['concourse-web']['environment']['CONCOURSE_POSTGRES_DATA_SOURCE'] = @data_source
 
 require 'yaml'
-yaml_str = config.to_hash.to_yaml
+yaml_str = config.to_yaml
 -%>
 <%= yaml_str %>
index 38e714d..bdaf873 100644 (file)
@@ -2,7 +2,7 @@ name 'concourse'
 description 'Concourse'
 
 run_list(
-  #'recipe[ssl_cert::server_key_pairs]',
+  #'recipe[ssl_cert::server_key_pairs]',  # for https
   'role[docker]',
   'recipe[concourse-ci::docker-compose]',
 )
@@ -12,13 +12,18 @@ run_list(
 #default_attributes()
 
 image = 'concourse/concourse'  # of 'concourse/concourse:2.6.0',...
-port = '8080'
+port = '8080'  # '8443' (for https)
 concourse_cn = 'concourse.io.example.com'
 
 override_attributes(
+  # for https
+  'ssl_cert' => {
+    'common_names' => [
+      concourse_cn,
+    ],
+  },
   'concourse-ci' => {
-    # Not supported yet.
-    'with_ssl_cert_cookbook' => false,
+    'with_ssl_cert_cookbook' => false,  # or true (for https)
     'ssl_cert' => {
       'common_name' => concourse_cn,
     },
@@ -29,11 +34,21 @@ override_attributes(
           'image' => image,
           'ports' => [
             #"#{port}:8080",  # If you sepecify no value, Chef will sets '8080:8080'.
+            #"#{port}:8443",  # for https
           ],
           'environment' => {
             # If you sepecify no value, Chef will sets "http://#{node['ipaddress']}:8080".
-            #'CONCOURSE_EXTERNAL_URL' => "http://192.168.1.3:#{port}",
+            #'CONCOURSE_EXTERNAL_URL' => "http://192.168.1.3:#{port}",  # or "https://192.168.1.3:#{port}"
+            #'CONCOURSE_TLS_BIND_PORT' => '8443',  # activate HTTPS
+            # These environments will be set by the concourse-ci::docker-compose recipe automatically.
+            #'CONCOURSE_TLS_CERT' => '/root/server.crt',
+            #'CONCOURSE_TLS_KEY' => '/root/server.key',
           },
+          'volumes' => [
+            # These volumes will be set by the concourse-ci::docker-compose recipe automatically.
+            #"#{server_cert_path(node['concourse-ci']['ssl_cert']['common_name'])}:/root/server.crt:ro",
+            #"#{server_key_path(node['concourse-ci']['ssl_cert']['common_name'])}:/root/server.key:ro",
+          ],
         },
         'concourse-worker' => {
           'image' => image,
@@ -41,9 +56,4 @@ override_attributes(
       },
     },
   },
-  'ssl_cert' => {
-    'common_names' => [
-      concourse_cn,
-    ],
-  },
 )