diff --git a/ansible/roles/common/defaults/main.yml b/ansible/roles/common/defaults/main.yml
index 491593793c..7952b5f7ee 100644
--- a/ansible/roles/common/defaults/main.yml
+++ b/ansible/roles/common/defaults/main.yml
@@ -72,6 +72,7 @@ fluentd_image_full: "{{ fluentd_image }}:{{ fluentd_tag }}"
syslog_swift_facility: "local0"
syslog_haproxy_facility: "local1"
+syslog_glance_tls_proxy_facility: "local2"
kolla_toolbox_default_volumes:
- "{{ node_config_directory }}/kolla-toolbox/:{{ container_config_directory }}/:ro"
@@ -125,6 +126,8 @@ fluentd_input_openstack_services:
enabled: "{{ enable_freezer | bool }}"
- name: glance
enabled: "{{ enable_glance | bool }}"
+ - name: glance-tls-proxy
+ enabled: "{{ enable_glance | bool }}"
- name: gnocchi
enabled: "{{ enable_gnocchi | bool }}"
- name: heat
diff --git a/ansible/roles/common/tasks/config.yml b/ansible/roles/common/tasks/config.yml
index ecbfee9ad9..31bb143b48 100644
--- a/ansible/roles/common/tasks/config.yml
+++ b/ansible/roles/common/tasks/config.yml
@@ -294,6 +294,7 @@
- { name: "etcd", enabled: "{{ enable_etcd }}" }
- { name: "freezer", enabled: "{{ enable_freezer }}" }
- { name: "glance", enabled: "{{ enable_glance }}" }
+ - { name: "glance-tls-proxy", enabled: "{{ enable_glance }}" }
- { name: "global", enabled: "yes" }
- { name: "gnocchi", enabled: "{{ enable_gnocchi }}" }
- { name: "grafana", enabled: "{{ enable_grafana }}" }
diff --git a/ansible/roles/common/templates/conf/filter/00-record_transformer.conf.j2 b/ansible/roles/common/templates/conf/filter/00-record_transformer.conf.j2
index 911320798f..238efee3de 100644
--- a/ansible/roles/common/templates/conf/filter/00-record_transformer.conf.j2
+++ b/ansible/roles/common/templates/conf/filter/00-record_transformer.conf.j2
@@ -36,6 +36,13 @@
+
+ @type record_transformer
+
+ programname glance-tls-proxy
+
+
+
# Rename internal Fluent message field to match other logs. This removes
# all other fields by default, including the original message field. This is
# intented to avoid duplication of the log message and to prevent passing
diff --git a/ansible/roles/common/templates/conf/output/00-local.conf.j2 b/ansible/roles/common/templates/conf/output/00-local.conf.j2
index 71b5da2f3b..9b42b30850 100644
--- a/ansible/roles/common/templates/conf/output/00-local.conf.j2
+++ b/ansible/roles/common/templates/conf/output/00-local.conf.j2
@@ -105,3 +105,58 @@
{% endif %}
+
+
+ @type copy
+
+ @type file
+ path /var/log/kolla/glance-tls-proxy/glance-tls-proxy.*.log
+ output_tag false
+ output_time false
+ utc
+ append true
+ compress gzip
+
+{% if log_direct_to_elasticsearch %}
+
+ type elasticsearch
+ host {{ elasticsearch_address }}
+ port {{ elasticsearch_port }}
+ scheme {{ fluentd_elasticsearch_scheme }}
+{% if fluentd_elasticsearch_path != '' %}
+ path {{ fluentd_elasticsearch_path }}
+{% endif %}
+{% if fluentd_elasticsearch_scheme == 'https' %}
+ ssl_version {{ fluentd_elasticsearch_ssl_version }}
+ ssl_verify {{ fluentd_elasticsearch_ssl_verify }}
+{% endif %}
+{% if fluentd_elasticsearch_user != '' and fluentd_elasticsearch_password != ''%}
+ user {{ fluentd_elasticsearch_user }}
+ password {{ fluentd_elasticsearch_password }}
+{% endif %}
+ logstash_format true
+ logstash_prefix {{ kibana_log_prefix }}
+ flush_interval 15s
+ reconnect_on_error true
+ buffer_type file
+ buffer_path /var/lib/fluentd/data/elasticsearch.buffer/{{ syslog_glance_tls_proxy_facility }}.*
+
+{% elif enable_monasca | bool %}
+ type copy
+
+ @type monasca
+ keystone_url {{ keystone_internal_url }}
+ monasca_log_api {{ internal_protocol }}://{{ kolla_internal_fqdn | put_address_in_context('url') }}:{{ monasca_log_api_port }}
+ monasca_log_api_version v3.0
+ username {{ monasca_agent_user }}
+ password {{ monasca_agent_password }}
+ domain_id default
+ project_name {{ monasca_control_plane_project }}
+ message_field_name Payload
+ buffer_type file
+ buffer_path /var/lib/fluentd/data/monasca.buffer/{{ syslog_glance_tls_proxy_facility }}.*
+ max_retry_wait 1800s
+ disable_retry_limit true
+
+{% endif %}
+
diff --git a/ansible/roles/common/templates/cron-logrotate-glance-tls-proxy.conf.j2 b/ansible/roles/common/templates/cron-logrotate-glance-tls-proxy.conf.j2
new file mode 100644
index 0000000000..5f53099180
--- /dev/null
+++ b/ansible/roles/common/templates/cron-logrotate-glance-tls-proxy.conf.j2
@@ -0,0 +1,3 @@
+"/var/log/kolla/glance-tls-proxy/*.log"
+{
+}
diff --git a/ansible/roles/common/templates/cron.json.j2 b/ansible/roles/common/templates/cron.json.j2
index f207e3db3c..b050437e32 100644
--- a/ansible/roles/common/templates/cron.json.j2
+++ b/ansible/roles/common/templates/cron.json.j2
@@ -16,6 +16,7 @@
( 'etcd', enable_etcd ),
( 'freezer', enable_freezer ),
( 'glance', enable_glance ),
+ ( 'glance-tls-proxy', enable_glance ),
( 'gnocchi', enable_gnocchi ),
( 'grafana', enable_grafana ),
( 'haproxy', enable_haproxy ),
diff --git a/ansible/roles/glance/defaults/main.yml b/ansible/roles/glance/defaults/main.yml
index 9cbb3c74a1..145fd53683 100644
--- a/ansible/roles/glance/defaults/main.yml
+++ b/ansible/roles/glance/defaults/main.yml
@@ -14,7 +14,7 @@ glance_services:
dimensions: "{{ glance_api_dimensions }}"
haproxy:
glance_api:
- enabled: "{{ enable_glance }}"
+ enabled: "{{ enable_glance | bool and not glance_enable_tls_backend | bool }}"
mode: "http"
external: false
port: "{{ glance_api_port }}"
@@ -24,7 +24,7 @@ glance_services:
- "timeout server {{ haproxy_glance_api_server_timeout }}"
custom_member_list: "{{ haproxy_members.split(';') }}"
glance_api_external:
- enabled: "{{ enable_glance }}"
+ enabled: "{{ enable_glance | bool and not glance_enable_tls_backend | bool }}"
mode: "http"
external: true
port: "{{ glance_api_port }}"
@@ -33,12 +33,43 @@ glance_services:
backend_http_extra:
- "timeout server {{ haproxy_glance_api_server_timeout }}"
custom_member_list: "{{ haproxy_members.split(';') }}"
-
+ glance-tls-proxy:
+ container_name: glance_tls_proxy
+ group: glance-api
+ host_in_groups: "{{ inventory_hostname in glance_api_hosts }}"
+ enabled: "{{ glance_enable_tls_backend }}"
+ image: "{{ glance_tls_proxy_image_full }}"
+ volumes: "{{ glance_tls_proxy_default_volumes + glance_tls_proxy_extra_volumes }}"
+ dimensions: "{{ glance_tls_proxy_dimensions }}"
+ haproxy:
+ glance_tls_proxy:
+ enabled: "{{ enable_glance | bool and glance_enable_tls_backend | bool }}"
+ mode: "http"
+ external: false
+ port: "{{ glance_api_port }}"
+ frontend_http_extra:
+ - "timeout client {{ haproxy_glance_api_client_timeout }}"
+ backend_http_extra:
+ - "timeout server {{ haproxy_glance_api_server_timeout }}"
+ custom_member_list: "{{ haproxy_tls_members.split(';') }}"
+ tls_backend: "yes"
+ glance_tls_proxy_external:
+ enabled: "{{ enable_glance | bool and glance_enable_tls_backend | bool }}"
+ mode: "http"
+ external: true
+ port: "{{ glance_api_port }}"
+ frontend_http_extra:
+ - "timeout client {{ haproxy_glance_api_client_timeout }}"
+ backend_http_extra:
+ - "timeout server {{ haproxy_glance_api_server_timeout }}"
+ custom_member_list: "{{ haproxy_tls_members.split(';') }}"
+ tls_backend: "yes"
####################
# HAProxy
####################
haproxy_members: "{% for host in glance_api_hosts %}server {{ hostvars[host]['ansible_hostname'] }} {{ 'api' | kolla_address(host) }}:{{ glance_api_listen_port }} check inter 2000 rise 2 fall 5;{% endfor %}"
+haproxy_tls_members: "{% for host in glance_api_hosts %}server {{ hostvars[host]['ansible_hostname'] }} {{ 'api' | kolla_address(host) }}:{{ glance_api_listen_port }} check inter 2000 rise 2 fall 5 ssl verify required ca-file {{ haproxy_backend_cacert }};{% endfor %}"
####################
# Keystone
@@ -92,7 +123,12 @@ glance_api_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ dock
glance_api_tag: "{{ glance_tag }}"
glance_api_image_full: "{{ glance_api_image }}:{{ glance_api_tag }}"
+glance_tls_proxy_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ glance_install_type }}-haproxy"
+glance_tls_proxy_tag: "{{ glance_tag }}"
+glance_tls_proxy_image_full: "{{ glance_tls_proxy_image }}:{{ glance_tls_proxy_tag }}"
+
glance_api_dimensions: "{{ default_container_dimensions }}"
+glance_tls_proxy_dimensions: "{{ default_container_dimensions }}"
glance_api_default_volumes:
- "{{ node_config_directory }}/glance-api/:{{ container_config_directory }}/:ro"
@@ -104,9 +140,15 @@ glance_api_default_volumes:
# NOTE(yoctozepto): below to support Cinder iSCSI backends
- "{% if enable_cinder | bool and enable_cinder_backend_iscsi | bool %}iscsi_info:/etc/iscsi{% endif %}"
- "{% if enable_cinder | bool and enable_cinder_backend_iscsi | bool %}/dev:/dev{% endif %}"
+glance_tls_proxy_default_volumes:
+ - "{{ node_config_directory }}/glance-tls-proxy/:{{ container_config_directory }}/:ro"
+ - "/etc/localtime:/etc/localtime:ro"
+ - "{{ '/etc/timezone:/etc/timezone:ro' if kolla_base_distro in ['debian', 'ubuntu'] else '' }}"
+ - "kolla_logs:/var/log/kolla/"
glance_extra_volumes: "{{ default_extra_volumes }}"
glance_api_extra_volumes: "{{ glance_extra_volumes }}"
+glance_tls_proxy_extra_volumes: "{{ glance_extra_volumes }}"
####################
# Glance
@@ -166,3 +208,27 @@ vmware_datastore_name:
###################
# Default maximum size of 10Gb
glance_cache_max_size: "10737418240"
+
+####################
+# TLS
+####################
+glance_enable_tls_backend: "{{ kolla_enable_tls_backend }}"
+
+####################
+# Backend TLS proxy
+####################
+syslog_server: "{{ api_interface_address }}"
+syslog_glance_tls_proxy_facility: "local2"
+
+glance_tls_proxy_max_connections: 40000
+glance_tls_proxy_processes: 1
+glance_tls_proxy_process_cpu_map: "no"
+glance_tls_proxy_defaults_max_connections: 10000
+glance_tls_proxy_http_request_timeout: "10s"
+glance_tls_proxy_queue_timeout: "1m"
+glance_tls_proxy_connect_timeout: "10s"
+glance_tls_proxy_client_timeout: "{{ haproxy_glance_api_client_timeout}}"
+glance_tls_proxy_server_timeout: "{{ haproxy_glance_api_server_timeout }}"
+glance_tls_proxy_check_timeout: "10s"
+# Check http://www.haproxy.org/download/1.5/doc/configuration.txt for available options
+glance_tls_proxy_defaults_balance: "roundrobin"
diff --git a/ansible/roles/glance/handlers/main.yml b/ansible/roles/glance/handlers/main.yml
index e3370f8d9c..5abf923756 100644
--- a/ansible/roles/glance/handlers/main.yml
+++ b/ansible/roles/glance/handlers/main.yml
@@ -15,3 +15,18 @@
dimensions: "{{ service.dimensions }}"
when:
- kolla_action != "config"
+
+- name: Restart glance-tls-proxy container
+ vars:
+ service_name: "glance-tls-proxy"
+ service: "{{ glance_services[service_name] }}"
+ become: true
+ kolla_docker:
+ action: "recreate_or_restart_container"
+ common_options: "{{ docker_common_options }}"
+ name: "{{ service.container_name }}"
+ image: "{{ service.image }}"
+ volumes: "{{ service.volumes|reject('equalto', '')|list }}"
+ dimensions: "{{ service.dimensions }}"
+ when:
+ - kolla_action != "config"
diff --git a/ansible/roles/glance/tasks/check-containers.yml b/ansible/roles/glance/tasks/check-containers.yml
index 7739559377..548fff7cf1 100644
--- a/ansible/roles/glance/tasks/check-containers.yml
+++ b/ansible/roles/glance/tasks/check-containers.yml
@@ -6,7 +6,7 @@
common_options: "{{ docker_common_options }}"
name: "{{ item.value.container_name }}"
image: "{{ item.value.image }}"
- privileged: "{{ item.value.privileged }}"
+ privileged: "{{ item.value.privileged | default(omit) }}"
environment: "{{ item.value.environment | default(omit) }}"
volumes: "{{ item.value.volumes|reject('equalto', '')|list }}"
dimensions: "{{ item.value.dimensions }}"
diff --git a/ansible/roles/glance/tasks/config.yml b/ansible/roles/glance/tasks/config.yml
index 0874a2576c..4d4240ecd5 100644
--- a/ansible/roles/glance/tasks/config.yml
+++ b/ansible/roles/glance/tasks/config.yml
@@ -37,7 +37,18 @@
- include_tasks: copy-certs.yml
when:
- - kolla_copy_ca_into_containers | bool
+ - kolla_copy_ca_into_containers | bool or glance_enable_tls_backend | bool
+
+- name: Creating TLS backend PEM File
+ assemble:
+ src: "{{ node_config_directory }}/glance-tls-proxy/"
+ dest: "{{ node_config_directory }}/glance-tls-proxy/glance-cert-and-key.pem"
+ mode: "0660"
+ regexp: "^glance-(cert|key)\\.pem$"
+ remote_src: true
+ become: true
+ when:
+ - glance_enable_tls_backend | bool
- name: Copying over config.json files for services
template:
@@ -52,25 +63,24 @@
notify:
- Restart {{ item.key }} container
-- name: Copying over glance-*.conf
+- name: Copying over glance-api.conf
vars:
- service_name: "{{ item.key }}"
+ glance_api: "{{ glance_services['glance-api'] }}"
merge_configs:
sources:
- - "{{ role_path }}/templates/{{ item.key }}.conf.j2"
+ - "{{ role_path }}/templates/glance-api.conf.j2"
- "{{ node_custom_config }}/global.conf"
- "{{ node_custom_config }}/glance.conf"
- - "{{ node_custom_config }}/glance/{{ item.key }}.conf"
- - "{{ node_custom_config }}/glance/{{ inventory_hostname }}/{{ item.key }}.conf"
- dest: "{{ node_config_directory }}/{{ item.key }}/{{ item.key }}.conf"
+ - "{{ node_custom_config }}/glance/glance-api.conf"
+ - "{{ node_custom_config }}/glance/{{ inventory_hostname }}/glance-api.conf"
+ dest: "{{ node_config_directory }}/glance-api/glance-api.conf"
mode: "0660"
become: true
when:
- - item.value.enabled | bool
- - item.value.host_in_groups | bool
- with_dict: "{{ glance_services }}"
+ - glance_api.enabled | bool
+ - glance_api.host_in_groups | bool
notify:
- - Restart {{ item.key }} container
+ - Restart glance-api container
- name: Copying over glance-cache.conf for glance_api
vars:
@@ -111,18 +121,37 @@
- Restart glance-api container
- name: Copying over existing policy file
+ vars:
+ glance_api: "{{ glance_services['glance-api'] }}"
template:
src: "{{ glance_policy_file_path }}"
- dest: "{{ node_config_directory }}/{{ item.key }}/{{ glance_policy_file }}"
+ dest: "{{ node_config_directory }}/glance-api/{{ glance_policy_file }}"
mode: "0660"
become: true
when:
- glance_policy_file is defined
- - item.value.host_in_groups | bool
- - item.value.enabled | bool
- with_dict: "{{ glance_services }}"
+ - glance_api.host_in_groups | bool
+ - glance_api.enabled | bool
notify:
- - Restart {{ item.key }} container
+ - Restart glance-api container
+
+- name: Copying over glance-haproxy-tls.cfg
+ vars:
+ glance_tls_proxy: "{{ glance_services['glance-tls-proxy'] }}"
+ template:
+ src: "{{ item }}"
+ dest: "{{ node_config_directory }}/glance-tls-proxy/glance-tls-proxy.cfg"
+ mode: "0660"
+ become: true
+ with_first_found:
+ - "{{ node_custom_config }}/glance/{{ inventory_hostname }}/glance-tls-proxy.cfg"
+ - "{{ node_custom_config }}/glance/glance-tls-proxy.cfg"
+ - "glance-tls-proxy.cfg.j2"
+ when:
+ - glance_tls_proxy.enabled | bool
+ - glance_tls_proxy.host_in_groups | bool
+ notify:
+ - Restart glance-tls-proxy container
- include_tasks: check-containers.yml
when: kolla_action != "config"
diff --git a/ansible/roles/glance/templates/glance-api.conf.j2 b/ansible/roles/glance/templates/glance-api.conf.j2
index 296ba757d1..2964503029 100644
--- a/ansible/roles/glance/templates/glance-api.conf.j2
+++ b/ansible/roles/glance/templates/glance-api.conf.j2
@@ -5,7 +5,11 @@ debug = {{ glance_logging_debug }}
log_file = /var/log/kolla/glance/glance-api.log
use_forwarded_for = true
+{% if glance_enable_tls_backend | bool %}
+bind_host = 127.0.0.1
+{% else %}
bind_host = {{ api_interface_address }}
+{% endif %}
bind_port = {{ glance_api_listen_port }}
workers = {{ openstack_service_workers }}
diff --git a/ansible/roles/glance/templates/glance-tls-proxy.cfg.j2 b/ansible/roles/glance/templates/glance-tls-proxy.cfg.j2
new file mode 100644
index 0000000000..d58b00420d
--- /dev/null
+++ b/ansible/roles/glance/templates/glance-tls-proxy.cfg.j2
@@ -0,0 +1,37 @@
+#jinja2: lstrip_blocks: True
+global
+ chroot /var/lib/haproxy
+ user glance
+ group glance
+ daemon
+ log {{ syslog_server }}:{{ syslog_udp_port }} {{ syslog_glance_tls_proxy_facility }}
+ maxconn {{ glance_tls_proxy_max_connections }}
+ nbproc {{ glance_tls_proxy_processes }}
+ {% if (glance_tls_proxy_processes | int > 1) and (glance_tls_proxy_process_cpu_map | bool) %}
+ {% for cpu_idx in range(0, glance_tls_proxy_processes) %}
+ cpu-map {{ cpu_idx + 1 }} {{ cpu_idx }}
+ {% endfor %}
+ {% endif %}
+ ssl-default-bind-ciphers DEFAULT:!MEDIUM:!3DES
+ ssl-default-bind-options no-sslv3 no-tlsv10 no-tlsv11
+ tune.ssl.default-dh-param 4096
+
+defaults
+ log global
+ option redispatch
+ retries 3
+ timeout http-request {{ glance_tls_proxy_http_request_timeout }}
+ timeout queue {{ glance_tls_proxy_queue_timeout }}
+ timeout connect {{ glance_tls_proxy_connect_timeout }}
+ timeout client {{ glance_tls_proxy_client_timeout }}
+ timeout server {{ glance_tls_proxy_server_timeout }}
+ timeout check {{ glance_tls_proxy_check_timeout }}
+ balance {{ glance_tls_proxy_defaults_balance }}
+ maxconn {{ glance_tls_proxy_defaults_max_connections }}
+
+frontend glance_backend_tls
+ bind {{ api_interface_address }}:{{ glance_api_listen_port }} ssl crt /etc/glance/certs/glance-cert-and-key.pem
+ default_backend glance_api
+
+backend glance_api
+ server glance-api 127.0.0.1:{{ glance_api_listen_port }} check
diff --git a/ansible/roles/glance/templates/glance-tls-proxy.json.j2 b/ansible/roles/glance/templates/glance-tls-proxy.json.j2
new file mode 100644
index 0000000000..27546f2d17
--- /dev/null
+++ b/ansible/roles/glance/templates/glance-tls-proxy.json.j2
@@ -0,0 +1,17 @@
+{
+ "command": "/usr/sbin/haproxy -W -db -p /run/haproxy.pid -f /etc/glance/glance-tls-proxy.cfg",
+ "config_files": [
+ {
+ "source": "{{ container_config_directory }}/glance-tls-proxy.cfg",
+ "dest": "/etc/glance/glance-tls-proxy.cfg",
+ "owner": "glance",
+ "perm": "0600"
+ },
+ {
+ "source": "{{ container_config_directory }}/glance-cert-and-key.pem",
+ "dest": "/etc/glance/certs/glance-cert-and-key.pem",
+ "owner": "glance",
+ "perm": "0600"
+ }
+ ]
+}
diff --git a/doc/source/admin/advanced-configuration.rst b/doc/source/admin/advanced-configuration.rst
index 34c21a06ed..bed050a5c0 100644
--- a/doc/source/admin/advanced-configuration.rst
+++ b/doc/source/admin/advanced-configuration.rst
@@ -382,6 +382,10 @@ By default, Swift and HAProxy use ``local0`` and ``local1``, respectively.
syslog_swift_facility: "local0"
syslog_haproxy_facility: "local1"
+If Glance TLS backend is enabled (``glance_enable_tls_backend``), the syslog
+facility for the ``glance_tls_proxy`` service uses ``local2`` by default. This
+can be set via ``syslog_glance_tls_proxy_facility``.
+
Mount additional Docker volumes in containers
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/releasenotes/notes/encrypt-backend-haproxy-fb96285d74fb464c.yaml b/releasenotes/notes/encrypt-backend-haproxy-fb96285d74fb464c.yaml
index 61baa77537..7385b29302 100644
--- a/releasenotes/notes/encrypt-backend-haproxy-fb96285d74fb464c.yaml
+++ b/releasenotes/notes/encrypt-backend-haproxy-fb96285d74fb464c.yaml
@@ -2,6 +2,7 @@
features:
- |
Added configuration options to enable backend TLS encryption from HAProxy
- to the Keystone, Heat, and cinder service. When used in conjunction with
- enabling TLS for service API endpoints, network communcation will be
- encrypted end to end, from client through HAProxy to the backend service.
+ to the Keystone, Glance, Heat, and Cinder services. When used in
+ conjunction with enabling TLS for service API endpoints, network
+ communcation will be encrypted end to end, from client through HAProxy to
+ the backend service.