Inject TLS certificate and keys for the Overcloud
authorJuan Antonio Osorio Robles <jaosorior@redhat.com>
Tue, 3 Nov 2015 13:19:18 +0000 (15:19 +0200)
committerJuan Antonio Osorio Robles <jaosorior@redhat.com>
Mon, 23 Nov 2015 09:55:26 +0000 (11:55 +0200)
This is a first implementation of adding TLS termination to the load
balancer in the controllers. The implementation was made so that the
appropriate certificate/private key in PEM format is copied to the
appropriate controller(s) via a software deployment resource.

And the path is then referenced on the HAProxy configuration, but this
part was left commented out because we need to be able to configure the
keystone endpoints in order for this to work properly.

Change-Id: I0ba8e38d75a0c628d8132a66dc25a30fc5183c79

environments/enable-tls.yaml [new file with mode: 0644]
overcloud-resource-registry-puppet.yaml
overcloud-without-mergepy.yaml
puppet/controller.yaml
puppet/extraconfig/tls/no-tls.yaml [new file with mode: 0644]
puppet/extraconfig/tls/tls-cert-inject.yaml [new file with mode: 0644]

diff --git a/environments/enable-tls.yaml b/environments/enable-tls.yaml
new file mode 100644 (file)
index 0000000..5c2506e
--- /dev/null
@@ -0,0 +1,9 @@
+parameter_defaults:
+  SSLCertificate: |
+    The contents of your certificate go here
+  SSLIntermediateCertificate: ''
+  SSLKey: |
+    The contents of the private key go here
+
+resource_registry:
+  OS::TripleO::NodeTLSData: ../puppet/extraconfig/tls/tls-cert-inject.yaml
index 4cfed6b..bf1cc25 100644 (file)
@@ -33,6 +33,7 @@ resource_registry:
   # NodeExtraConfig == All nodes configuration pre service deployment
   # NodeExtraConfigPost == All nodes configuration post service deployment
   OS::TripleO::NodeUserData: firstboot/userdata_default.yaml
+  OS::TripleO::NodeTLSData: puppet/extraconfig/tls/no-tls.yaml
   OS::TripleO::ControllerExtraConfigPre: puppet/extraconfig/pre_deploy/default.yaml
   OS::TripleO::ComputeExtraConfigPre: puppet/extraconfig/pre_deploy/default.yaml
   OS::TripleO::CephStorageExtraConfigPre: puppet/extraconfig/pre_deploy/default.yaml
index f679c6b..c3b95b9 100644 (file)
@@ -490,20 +490,6 @@ parameters:
         Specifies the interface where the public-facing virtual ip will be assigned.
         This should be int_public when a VLAN is being used.
     type: string
-  SSLCertificate:
-    default: ''
-    description: If set, the contents of an SSL certificate .crt file for encrypting SSL endpoints.
-    type: string
-    hidden: true
-  SSLKey:
-    default: ''
-    description: If set, the contents of an SSL certificate .key file for encrypting SSL endpoints.
-    type: string
-    hidden: true
-  SSLCACertificate:
-    default: ''
-    description: If set, the contents of an SSL certificate authority file.
-    type: string
   SwiftHashSuffix:
     default: unset
     description: A random string to be used as a salt when hashing to determine mappings in the ring.
@@ -880,9 +866,6 @@ resources:
           SnmpdReadonlyUserName: {get_param: SnmpdReadonlyUserName}
           SnmpdReadonlyUserPassword: {get_param: SnmpdReadonlyUserPassword}
           RedisVirtualIP: {get_attr: [RedisVirtualIP, ip_address]}
-          SSLCertificate: {get_param: SSLCertificate}
-          SSLKey: {get_param: SSLKey}
-          SSLCACertificate: {get_param: SSLCACertificate}
           SwiftHashSuffix: {get_param: SwiftHashSuffix}
           SwiftMountCheck: {get_param: SwiftMountCheck}
           SwiftMinPartHours: {get_param: SwiftMinPartHours}
@@ -911,6 +894,7 @@ resources:
               template: {get_param: ControllerHostnameFormat}
               params:
                 '%stackname%': {get_param: 'OS::stack_name'}
+          NodeIndex: '%index%'
 
   Compute:
     type: OS::Heat::ResourceGroup
index 0c921eb..e628921 100644 (file)
@@ -514,20 +514,6 @@ parameters:
     description: The user password for SNMPd with readonly rights running on all Overcloud nodes
     type: string
     hidden: true
-  SSLCACertificate:
-    default: ''
-    description: If set, the contents of an SSL certificate authority file.
-    type: string
-  SSLCertificate:
-    default: ''
-    description: If set, the contents of an SSL certificate .crt file for encrypting SSL endpoints.
-    type: string
-    hidden: true
-  SSLKey:
-    default: ''
-    description: If set, the contents of an SSL certificate .key file for encrypting SSL endpoints.
-    type: string
-    hidden: true
   SwiftHashSuffix:
     default: unset
     description: A random string to be used as a salt when hashing to determine mappings
@@ -611,6 +597,9 @@ parameters:
     description: >
       Heat action when to apply network configuration changes
     default: ['CREATE']
+  NodeIndex:
+    type: number
+    default: 0
 
 resources:
 
@@ -712,6 +701,14 @@ resources:
         bridge_name: br-ex
         interface_name: {get_param: NeutronPublicInterface}
 
+  # Hook for site-specific passing of private keys/certificates
+  NodeTLSData:
+    depends_on: NetworkDeployment
+    type: OS::TripleO::NodeTLSData
+    properties:
+      server: {get_resource: Controller}
+      NodeIndex: {get_param: NodeIndex}
+
   ControllerDeployment:
     type: OS::TripleO::SoftwareDeployment
     depends_on: NetworkDeployment
@@ -1289,6 +1286,12 @@ resources:
                 tripleo::loadbalancer::control_virtual_interface: {get_input: control_virtual_interface}
                 tripleo::loadbalancer::public_virtual_interface: {get_input: public_virtual_interface}
                 tripleo::loadbalancer::haproxy_log_address: {get_input: haproxy_log_address}
+                # NOTE(jaosorior): The service certificate configuration for
+                # HAProxy was left commented because to properly use this, we
+                # need to be able to set up the keystone endpoints. And
+                # currently that is not possible, but is being addressed by
+                # other commits.  A subsequent commit will uncomment this.
+                #tripleo::loadbalancer::service_certificate: {get_attr: [NodeTLSData, deployed_ssl_certificate_path]}
                 tripleo::packages::enable_install: {get_input: enable_package_install}
                 tripleo::packages::enable_upgrade: {get_input: enable_package_upgrade}
 
@@ -1382,5 +1385,6 @@ outputs:
       list_join:
         - ','
         - - {get_attr: [ControllerDeployment, deploy_stdout]}
+          - {get_attr: [NodeTLSData, deploy_stdout]}
           - {get_attr: [ControllerExtraConfigPre, deploy_stdout]}
           - {get_param: UpdateIdentifier}
diff --git a/puppet/extraconfig/tls/no-tls.yaml b/puppet/extraconfig/tls/no-tls.yaml
new file mode 100644 (file)
index 0000000..d2dfdfa
--- /dev/null
@@ -0,0 +1,28 @@
+heat_template_version: 2015-04-30
+
+description: >
+  This is a default no-op template. This defines the parameters that
+  need to be passed in order to have TLS enabled in the controller
+  nodes. This template can be replaced with a different
+  implementation via the resource registry, such that deployers
+  may customize their configuration.
+
+parameters:
+  DeployedSSLCertificatePath:
+    default: ''
+    description: >
+        The filepath of the certificate as it will be stored in the controller.
+    type: string
+  NodeIndex: # Here for compatibility with tls-cert-inject.yaml
+    default: 0
+    type: number
+  server:    # Here for compatibility with tls-cert-inject.yaml
+    description: ID of the controller node to apply this config to
+    type: string
+
+outputs:
+  deploy_stdout:
+    description: Deployment reference, used to trigger puppet apply on changes
+    value: 'TLS not enabled.'
+  deployed_ssl_certificate_path:
+    value: ''
diff --git a/puppet/extraconfig/tls/tls-cert-inject.yaml b/puppet/extraconfig/tls/tls-cert-inject.yaml
new file mode 100644 (file)
index 0000000..b4564fc
--- /dev/null
@@ -0,0 +1,81 @@
+heat_template_version: 2015-04-30
+
+description: >
+  This is a template which will build the TLS Certificates necessary
+  for the load balancer using the given parameters.
+
+parameters:
+  # Can be overriden via parameter_defaults in the environment
+  SSLCertificate:
+    default: ''
+    description: >
+      The content of the SSL certificate (without Key) in PEM format.
+    type: string
+  SSLIntermediateCertificate:
+    default: ''
+    description: >
+      The content of an SSL intermediate CA certificate in PEM format.
+    type: string
+  SSLKey:
+    default: ''
+    description: >
+      The content of the SSL Key in PEM format.
+    type: string
+    hidden: true
+
+  # Can be overriden by parameter_defaults if the user wants to try deploying
+  # this in a distro that doesn't support this path.
+  DeployedSSLCertificatePath:
+    default: '/etc/pki/tls/private/overcloud_endpoint.pem'
+    description: >
+        The filepath of the certificate as it will be stored in the controller.
+    type: string
+
+  # Passed in by the controller
+  NodeIndex:
+    default: 0
+    type: number
+  server:
+    description: ID of the controller node to apply this config to
+    type: string
+
+resources:
+  ControllerTLSConfig:
+    type: OS::Heat::SoftwareConfig
+    properties:
+      group: script
+      inputs:
+        - name: cert_path
+        - name: cert_chain_content
+      outputs:
+        - name: chain_md5sum
+      config: |
+        #!/bin/sh
+        cat << EOF | tee ${cert_path} > /dev/null
+        ${cert_chain_content}
+        EOF
+        chmod 0440 ${cert_path}
+        chown root:haproxy ${cert_path}
+        md5sum ${cert_path} > ${heat_outputs_path}.chain_md5sum
+
+  ControllerTLSDeployment:
+    type: OS::Heat::SoftwareDeployment
+    properties:
+      config: {get_resource: ControllerTLSConfig}
+      server: {get_param: server}
+      input_values:
+        cert_path: {get_param: DeployedSSLCertificatePath}
+        cert_chain_content:
+          list_join:
+            - ''
+            - - {get_param: SSLCertificate}
+              - {get_param: SSLIntermediateCertificate}
+              - {get_param: SSLKey}
+
+outputs:
+  deploy_stdout:
+    description: Deployment reference
+    value: {get_attr: [ControllerTLSDeployment, chain_md5sum]}
+  deployed_ssl_certificate_path:
+    description: The location that the TLS certificate was deployed to.
+    value: {get_param: DeployedSSLCertificatePath}