Add HAProxy TLS handled by certmonger as composable service
authorJuan Antonio Osorio Robles <jaosorior@redhat.com>
Wed, 17 Aug 2016 12:24:23 +0000 (12:24 +0000)
committerJuan Antonio Osorio Robles <jaosorior@redhat.com>
Thu, 29 Sep 2016 17:15:13 +0000 (17:15 +0000)
This adds some basic pieces to get certmonger to manage the
certificates for HAProxy. The aim is to be flexible enough that we
will be able to manage both public and internal certificates.

This also adds a relevant environment to get the endpoints to have
TLS everywhere.

bp tls-via-certmonger

Depends-On: I89001ae32f46c9682aecc118753ef6cd647baa62
Change-Id: Ife5f8c2f07233295bc15b4c605acf3d9bd62f162

environments/services/haproxy-internal-tls-certmonger.yaml [new file with mode: 0644]
environments/services/haproxy-public-tls-certmonger.yaml [new file with mode: 0644]
environments/tls-everywhere-endpoints-dns.yaml [new file with mode: 0644]
overcloud-resource-registry-puppet.j2.yaml
puppet/services/haproxy-internal-tls-certmonger.yaml [new file with mode: 0644]
puppet/services/haproxy-public-tls-certmonger.yaml [new file with mode: 0644]
puppet/services/haproxy.yaml

diff --git a/environments/services/haproxy-internal-tls-certmonger.yaml b/environments/services/haproxy-internal-tls-certmonger.yaml
new file mode 100644 (file)
index 0000000..074fec4
--- /dev/null
@@ -0,0 +1,4 @@
+# A Heat environment file which can be used to enable a
+# a TLS for HAProxy via certmonger
+resource_registry:
+  OS::TripleO::Services::HAProxyInternalTLS: ../../puppet/services/haproxy-internal-tls-certmonger.yaml
diff --git a/environments/services/haproxy-public-tls-certmonger.yaml b/environments/services/haproxy-public-tls-certmonger.yaml
new file mode 100644 (file)
index 0000000..d3ad3ad
--- /dev/null
@@ -0,0 +1,4 @@
+# A Heat environment file which can be used to enable a
+# a TLS for HAProxy via certmonger
+resource_registry:
+  OS::TripleO::Services::HAProxyPublicTLS: ../../puppet/services/haproxy-public-tls-certmonger.yaml
diff --git a/environments/tls-everywhere-endpoints-dns.yaml b/environments/tls-everywhere-endpoints-dns.yaml
new file mode 100644 (file)
index 0000000..88a108a
--- /dev/null
@@ -0,0 +1,52 @@
+# Use this environment when deploying an overcloud where all the endpoints are
+# DNS names and there's TLS in all endpoint types.
+parameter_defaults:
+  EndpointMap:
+    AodhAdmin: {protocol: 'https', port: '8042', host: 'CLOUDNAME'}
+    AodhInternal: {protocol: 'https', port: '8042', host: 'CLOUDNAME'}
+    AodhPublic: {protocol: 'https', port: '13042', host: 'CLOUDNAME'}
+    CeilometerAdmin: {protocol: 'https', port: '8777', host: 'CLOUDNAME'}
+    CeilometerInternal: {protocol: 'https', port: '8777', host: 'CLOUDNAME'}
+    CeilometerPublic: {protocol: 'https', port: '13777', host: 'CLOUDNAME'}
+    CinderAdmin: {protocol: 'https', port: '8776', host: 'CLOUDNAME'}
+    CinderInternal: {protocol: 'https', port: '8776', host: 'CLOUDNAME'}
+    CinderPublic: {protocol: 'https', port: '13776', host: 'CLOUDNAME'}
+    GlanceAdmin: {protocol: 'https', port: '9292', host: 'CLOUDNAME'}
+    GlanceInternal: {protocol: 'https', port: '9292', host: 'CLOUDNAME'}
+    GlancePublic: {protocol: 'https', port: '13292', host: 'CLOUDNAME'}
+    GlanceRegistryInternal: {protocol: 'https', port: '9191', host: 'CLOUDNAME'}
+    GnocchiAdmin: {protocol: 'https', port: '8041', host: 'CLOUDNAME'}
+    GnocchiInternal: {protocol: 'https', port: '8041', host: 'CLOUDNAME'}
+    GnocchiPublic: {protocol: 'https', port: '13041', host: 'CLOUDNAME'}
+    HeatAdmin: {protocol: 'https', port: '8004', host: 'CLOUDNAME'}
+    HeatInternal: {protocol: 'https', port: '8004', host: 'CLOUDNAME'}
+    HeatPublic: {protocol: 'https', port: '13004', host: 'CLOUDNAME'}
+    HeatCfnAdmin: {protocol: 'https', port: '8000', host: 'CLOUDNAME'}
+    HeatCfnInternal: {protocol: 'https', port: '8000', host: 'CLOUDNAME'}
+    HeatCfnPublic: {protocol: 'https', port: '13005', host: 'CLOUDNAME'}
+    HorizonPublic: {protocol: 'https', port: '443', host: 'CLOUDNAME'}
+    IronicAdmin: {protocol: 'https', port: '6385', host: 'CLOUDNAME'}
+    IronicInternal: {protocol: 'https', port: '6385', host: 'CLOUDNAME'}
+    IronicPublic: {protocol: 'https', port: '13385', host: 'CLOUDNAME'}
+    KeystoneAdmin: {protocol: 'https', port: '35357', host: 'CLOUDNAME'}
+    KeystoneInternal: {protocol: 'https', port: '5000', host: 'CLOUDNAME'}
+    KeystonePublic: {protocol: 'https', port: '13000', host: 'CLOUDNAME'}
+    ManilaAdmin: {protocol: 'https', port: '8786', host: 'CLOUDNAME'}
+    ManilaInternal: {protocol: 'https', port: '8786', host: 'CLOUDNAME'}
+    ManilaPublic: {protocol: 'https', port: '13786', host: 'CLOUDNAME'}
+    MysqlInternal: {protocol: 'mysql+pymysql', port: '3306', host: 'CLOUDNAME'}
+    NeutronAdmin: {protocol: 'https', port: '9696', host: 'CLOUDNAME'}
+    NeutronInternal: {protocol: 'https', port: '9696', host: 'CLOUDNAME'}
+    NeutronPublic: {protocol: 'https', port: '13696', host: 'CLOUDNAME'}
+    NovaAdmin: {protocol: 'https', port: '8774', host: 'CLOUDNAME'}
+    NovaInternal: {protocol: 'https', port: '8774', host: 'CLOUDNAME'}
+    NovaPublic: {protocol: 'https', port: '13774', host: 'CLOUDNAME'}
+    NovaVNCProxyAdmin: {protocol: 'https', port: '6080', host: 'CLOUDNAME'}
+    NovaVNCProxyInternal: {protocol: 'https', port: '6080', host: 'CLOUDNAME'}
+    NovaVNCProxyPublic: {protocol: 'https', port: '13080', host: 'CLOUDNAME'}
+    SaharaAdmin: {protocol: 'https', port: '8386', host: 'CLOUDNAME'}
+    SaharaInternal: {protocol: 'https', port: '8386', host: 'CLOUDNAME'}
+    SaharaPublic: {protocol: 'https', port: '13386', host: 'CLOUDNAME'}
+    SwiftAdmin: {protocol: 'https', port: '8080', host: 'CLOUDNAME'}
+    SwiftInternal: {protocol: 'https', port: '8080', host: 'CLOUDNAME'}
+    SwiftPublic: {protocol: 'https', port: '13808', host: 'CLOUDNAME'}
index a7185a4..5f09f52 100644 (file)
@@ -142,6 +142,8 @@ resource_registry:
   OS::TripleO::Services::NeutronSriovAgent: OS::Heat::None
   OS::TripleO::Services::RabbitMQ: puppet/services/rabbitmq.yaml
   OS::TripleO::Services::HAproxy: puppet/services/haproxy.yaml
+  OS::TripleO::Services::HAProxyPublicTLS: OS::Heat::None
+  OS::TripleO::Services::HAProxyInternalTLS: OS::Heat::None
   OS::TripleO::Services::Keepalived: puppet/services/keepalived.yaml
   OS::TripleO::Services::Memcached: puppet/services/memcached.yaml
   OS::TripleO::Services::SaharaApi: OS::Heat::None
diff --git a/puppet/services/haproxy-internal-tls-certmonger.yaml b/puppet/services/haproxy-internal-tls-certmonger.yaml
new file mode 100644 (file)
index 0000000..c6d5354
--- /dev/null
@@ -0,0 +1,51 @@
+heat_template_version: 2016-10-14
+
+description: >
+  HAProxy deployment with TLS enabled, powered by certmonger
+
+parameters:
+  ServiceNetMap:
+    default: {}
+    description: Mapping of service_name -> network name. Typically set
+                 via parameter_defaults in the resource registry.  This
+                 mapping overrides those in ServiceNetMapDefaults.
+    type: json
+  DefaultPasswords:
+    default: {}
+    type: json
+  EndpointMap:
+    default: {}
+    description: Mapping of service endpoint -> protocol. Typically set
+                 via parameter_defaults in the resource registry.
+    type: json
+
+outputs:
+  role_data:
+    description: Role data for the HAProxy internal TLS via certmonger role.
+    value:
+      service_name: haproxy_internal_tls_certmonger
+      config_settings:
+        generate_service_certificates: true
+        tripleo::haproxy::use_internal_certificates: true
+      certificates_specs:
+        map_merge:
+          repeat:
+            template:
+              haproxy-NETWORK:
+                service_pem: '/etc/pki/tls/certs/overcloud-haproxy-NETWORK.pem'
+                service_certificate: '/etc/pki/tls/certs/overcloud-haproxy-NETWORK.crt'
+                service_key: '/etc/pki/tls/private/overcloud-haproxy-NETWORK.key'
+                hostname: "%{hiera('cloud_name_NETWORK')}"
+                postsave_cmd: "" # TODO
+                principal: "haproxy/%{hiera('cloud_name_NETWORK')}"
+            for_each:
+              NETWORK:
+                # NOTE(jaosorior) Get unique network names to create
+                # certificates for those. We skip the tenant network since
+                # we don't need a certificate for that, and the external
+                # network will be handled in another template.
+                yaql:
+                  expression: list($.data.map.items().map($1[1])).distinct().where($ != external and $ != tenant)
+                  data:
+                    map:
+                      get_param: ServiceNetMap
diff --git a/puppet/services/haproxy-public-tls-certmonger.yaml b/puppet/services/haproxy-public-tls-certmonger.yaml
new file mode 100644 (file)
index 0000000..1551d16
--- /dev/null
@@ -0,0 +1,37 @@
+heat_template_version: 2016-10-14
+
+description: >
+  HAProxy deployment with TLS enabled, powered by certmonger
+
+parameters:
+  ServiceNetMap:
+    default: {}
+    description: Mapping of service_name -> network name. Typically set
+                 via parameter_defaults in the resource registry.  This
+                 mapping overrides those in ServiceNetMapDefaults.
+    type: json
+  DefaultPasswords:
+    default: {}
+    type: json
+  EndpointMap:
+    default: {}
+    description: Mapping of service endpoint -> protocol. Typically set
+                 via parameter_defaults in the resource registry.
+    type: json
+
+outputs:
+  role_data:
+    description: Role data for the HAProxy public TLS via certmonger role.
+    value:
+      service_name: haproxy_public_tls_certmonger
+      config_settings:
+        generate_service_certificates: true
+        tripleo::haproxy::service_certificate: '/etc/pki/tls/certs/overcloud-haproxy-external.pem'
+      certificates_specs:
+        haproxy-external:
+          service_pem: '/etc/pki/tls/certs/overcloud-haproxy-external.pem'
+          service_certificate: '/etc/pki/tls/certs/overcloud-haproxy-external.crt'
+          service_key: '/etc/pki/tls/private/overcloud-haproxy-external.key'
+          hostname: "%{hiera('cloud_name_external')}"
+          postsave_cmd: "" # TODO
+          principal: "haproxy/%{hiera('cloud_name_external')}"
index 974928c..0813cb7 100644 (file)
@@ -1,4 +1,4 @@
-heat_template_version: 2016-04-08
+heat_template_version: 2016-10-14
 
 description: >
   HAproxy service configured with Puppet
@@ -48,6 +48,22 @@ parameters:
     default: 'overcloud-haproxy'
     type: string
 
+resources:
+
+  HAProxyPublicTLS:
+    type: OS::TripleO::Services::HAProxyPublicTLS
+    properties:
+      ServiceNetMap: {get_param: ServiceNetMap}
+      DefaultPasswords: {get_param: DefaultPasswords}
+      EndpointMap: {get_param: EndpointMap}
+
+  HAProxyInternalTLS:
+    type: OS::TripleO::Services::HAProxyInternalTLS
+    properties:
+      ServiceNetMap: {get_param: ServiceNetMap}
+      DefaultPasswords: {get_param: DefaultPasswords}
+      EndpointMap: {get_param: EndpointMap}
+
 outputs:
   role_data:
     description: Role data for the HAproxy role.
@@ -55,14 +71,21 @@ outputs:
       service_name: haproxy
       monitoring_subscription: {get_param: MonitoringSubscriptionHaproxy}
       config_settings:
-        tripleo.haproxy.firewall_rules:
-          '107 haproxy stats':
-            dport: 1993
-        tripleo::haproxy::haproxy_log_address: {get_param: HAProxySyslogAddress}
-        tripleo::haproxy::haproxy_stats_user: {get_param: HAProxyStatsUser}
-        tripleo::haproxy::haproxy_stats_password: {get_param: HAProxyStatsPassword}
-        tripleo::haproxy::redis_password: {get_param: RedisPassword}
-        tripleo::haproxy::control_virtual_interface: {get_param: ControlVirtualInterface}
-        tripleo::haproxy::public_virtual_interface: {get_param: PublicVirtualInterface}
+        map_merge:
+          - get_attr: [HAProxyPublicTLS, role_data, config_settings]
+          - get_attr: [HAProxyInternalTLS, role_data, config_settings]
+          - tripleo.haproxy.firewall_rules:
+              '107 haproxy stats':
+                dport: 1993
+            tripleo::haproxy::haproxy_log_address: {get_param: HAProxySyslogAddress}
+            tripleo::haproxy::haproxy_stats_user: {get_param: HAProxyStatsUser}
+            tripleo::haproxy::haproxy_stats_password: {get_param: HAProxyStatsPassword}
+            tripleo::haproxy::redis_password: {get_param: RedisPassword}
+            tripleo::haproxy::control_virtual_interface: {get_param: ControlVirtualInterface}
+            tripleo::haproxy::public_virtual_interface: {get_param: PublicVirtualInterface}
+            tripleo::profile::base::haproxy::certificates_specs:
+              map_merge:
+                - get_attr: [HAProxyPublicTLS, role_data, certificates_specs]
+                - get_attr: [HAProxyInternalTLS, role_data, certificates_specs]
       step_config: |
         include ::tripleo::profile::base::haproxy