tripleo-heat-templates/deployment/nova/nova-api-container-puppet.yaml
Oliver Walsh a2a6ddab59 Refactor nova db config
It is best to avoid placing db creds on the compute nodes to limit the
exposure if an attacker succeeds in gaining access to the hypervisor
host.

Related patches in puppet-nova remove the credentials from nova.conf
however the current scope of db credential hieradata is all nova tripleo
services - so it will but written to the hieradata keys on compute
nodes.

This patch refactors the nova hieradata structure, splitting the
nova-api/nova database hieradata out into individual templates and
selectively including only where necessary, ensuring we have no db
creds on a compute node (unless it is an all-in-one api+compute node).

Conflicts:
	deployment/nova/nova-manager-container-puppet.yaml
        deployment/nova/nova-compute-common-container-puppet.yaml

Depends-On: I07caa3185427b48e6e7d60965fa3e6157457018c
Change-Id: Ia4a29bdd2cd8e894bcc7c0078cf0f0ab0f97de0a
Closes-bug: #1871482
(cherry picked from commit 9d82364de8)
2021-01-04 16:07:52 -05:00

538 lines
20 KiB
YAML

heat_template_version: rocky
description: >
OpenStack containerized Nova API service
parameters:
ContainerNovaApiImage:
description: image
type: string
ContainerNovaConfigImage:
description: The container image to use for the nova config_volume
type: string
NovaApiLoggingSource:
type: json
default:
tag: openstack.nova.api
file: /var/log/containers/nova/nova-api.log
EndpointMap:
default: {}
description: Mapping of service endpoint -> protocol. Typically set
via parameter_defaults in the resource registry.
type: json
ServiceData:
default: {}
description: Dictionary packing service data
type: json
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
RoleName:
default: ''
description: Role name on which the service is applied
type: string
RoleParameters:
default: {}
description: Parameters specific to the role
type: json
DeployIdentifier:
default: ''
type: string
description: >
Setting this to a unique value will re-run any deployment tasks which
perform configuration on a Heat stack-update.
EnableInternalTLS:
type: boolean
default: false
NovaDbSyncTimeout:
default: 300
description: Timeout for Nova db sync
type: number
NovaPassword:
description: The password for the nova service and db account
type: string
hidden: true
MysqlIPv6:
default: false
description: Enable IPv6 in MySQL
type: boolean
NovaWorkers:
default: 0
description: Number of workers for Nova services.
type: number
KeystoneRegion:
type: string
default: 'regionOne'
description: Keystone region for endpoint
InstanceNameTemplate:
default: 'instance-%08x'
description: Template string to be used to generate instance names
type: string
NovaEnableDBPurge:
default: true
description: |
Whether to create cron job for purging soft deleted rows in Nova database.
type: boolean
NovaEnableDBArchive:
default: true
description: |
Whether to create cron job for archiving soft deleted rows in Nova database.
type: boolean
MonitoringSubscriptionNovaApi:
default: 'overcloud-nova-api'
type: string
NovaDefaultFloatingPool:
default: 'public'
description: Default pool for floating IP addresses
type: string
NovaApiPolicies:
description: |
A hash of policies to configure for Nova API.
e.g. { nova-context_is_admin: { key: context_is_admin, value: 'role:admin' } }
default: {}
type: json
NovaAllowResizeToSameHost:
default: false
description: Allow destination machine to match source for resize.
type: boolean
NovaApiMaxLimit:
default: 1000
description: Max number of objects returned per API query
type: number
parameter_groups:
- label: deprecated
description: |
The following parameters are deprecated and will be removed. They should not
be relied on for new deployments. If you have concerns regarding deprecated
parameters, please contact the TripleO development team on IRC or the
OpenStack mailing list.
parameters:
- MysqlIPv6
conditions:
internal_tls_enabled: {equals: [{get_param: EnableInternalTLS}, true]}
mysql_ipv6_use_ip_address:
and:
- {equals: [{get_param: [ServiceData, net_ip_version_map, {get_param: [ServiceNetMap, MysqlNetwork]}]}, 6]}
- {equals: [{get_param: EnableInternalTLS}, false]}
nova_workers_zero: {equals : [{get_param: NovaWorkers}, 0]}
resources:
ContainersCommon:
type: ../containers-common.yaml
MySQLClient:
type: ../../deployment/database/mysql-client.yaml
NovaApiLogging:
type: OS::TripleO::Services::Logging::NovaApi
ApacheServiceBase:
type: ../../deployment/apache/apache-baremetal-puppet.yaml
properties:
ServiceData: {get_param: ServiceData}
ServiceNetMap: {get_param: ServiceNetMap}
DefaultPasswords: {get_param: DefaultPasswords}
EndpointMap: {get_param: EndpointMap}
RoleName: {get_param: RoleName}
RoleParameters: {get_param: RoleParameters}
EnableInternalTLS: {get_param: EnableInternalTLS}
NovaBase:
type: ./nova-base-puppet.yaml
properties:
ServiceData: {get_param: ServiceData}
ServiceNetMap: {get_param: ServiceNetMap}
DefaultPasswords: {get_param: DefaultPasswords}
EndpointMap: {get_param: EndpointMap}
RoleName: {get_param: RoleName}
RoleParameters: {get_param: RoleParameters}
NovaApiDBClient:
type: ./nova-apidb-client-puppet.yaml
properties:
ServiceData: {get_param: ServiceData}
ServiceNetMap: {get_param: ServiceNetMap}
DefaultPasswords: {get_param: DefaultPasswords}
EndpointMap: {get_param: EndpointMap}
RoleName: {get_param: RoleName}
RoleParameters: {get_param: RoleParameters}
NovaDBClient:
type: ./nova-db-client-puppet.yaml
properties:
ServiceData: {get_param: ServiceData}
ServiceNetMap: {get_param: ServiceNetMap}
DefaultPasswords: {get_param: DefaultPasswords}
EndpointMap: {get_param: EndpointMap}
RoleName: {get_param: RoleName}
RoleParameters: {get_param: RoleParameters}
outputs:
role_data:
description: Role data for the Nova API role.
value:
service_name: nova_api
firewall_rules:
'113 nova_api':
dport:
- 8774
- 13774
keystone_resources:
nova:
endpoints:
public: {get_param: [EndpointMap, NovaPublic, uri]}
internal: {get_param: [EndpointMap, NovaInternal, uri]}
admin: {get_param: [EndpointMap, NovaAdmin, uri]}
users:
nova:
roles:
- admin
- service
password: {get_param: NovaPassword}
region: {get_param: KeystoneRegion}
service: 'compute'
monitoring_subscription: {get_param: MonitoringSubscriptionNovaApi}
config_settings:
map_merge:
- get_attr: [NovaBase, role_data, config_settings]
- get_attr: [NovaApiDBClient, role_data, config_settings]
- get_attr: [NovaDBClient, role_data, config_settings]
- get_attr: [NovaApiLogging, config_settings]
- apache::default_vhost: false
nova::keystone::authtoken::project_name: 'service'
nova::keystone::authtoken::user_domain_name: 'Default'
nova::keystone::authtoken::project_domain_name: 'Default'
nova::keystone::authtoken::password: {get_param: NovaPassword}
nova::keystone::authtoken::www_authenticate_uri: {get_param: [EndpointMap, KeystoneInternal, uri_no_suffix] }
nova::keystone::authtoken::auth_url: {get_param: [EndpointMap, KeystoneInternal, uri_no_suffix]}
nova::keystone::authtoken::region_name: {get_param: KeystoneRegion}
nova::keystone::authtoken::interface: 'internal'
nova::api::max_limit: {get_param: NovaApiMaxLimit}
nova::api::enabled: true
nova::api::default_floating_pool: {get_param: NovaDefaultFloatingPool}
nova::api::enable_proxy_headers_parsing: true
nova::api::api_bind_address:
str_replace:
template:
"%{hiera('fqdn_$NETWORK')}"
params:
$NETWORK: {get_param: [ServiceNetMap, NovaApiNetwork]}
nova::api::service_name: 'httpd'
nova::wsgi::apache_api::ssl: {get_param: EnableInternalTLS}
# NOTE: bind IP is found in hiera replacing the network name with the local node IP
# for the given network; replacement examples (eg. for internal_api):
# internal_api -> IP
# internal_api_uri -> [IP]
# internal_api_subnet - > IP/CIDR
nova::wsgi::apache_api::bind_host:
str_replace:
template:
"%{hiera('$NETWORK')}"
params:
$NETWORK: {get_param: [ServiceNetMap, NovaApiNetwork]}
nova::wsgi::apache_api::servername:
str_replace:
template:
"%{hiera('fqdn_$NETWORK')}"
params:
$NETWORK: {get_param: [ServiceNetMap, NovaApiNetwork]}
nova::api::instance_name_template: {get_param: InstanceNameTemplate}
nova_enable_db_purge: {get_param: NovaEnableDBPurge}
nova_enable_db_archive: {get_param: NovaEnableDBArchive}
nova::policy::policies: {get_param: NovaApiPolicies}
nova::api::allow_resize_to_same_host: {get_param: NovaAllowResizeToSameHost}
-
if:
- nova_workers_zero
- {}
- nova::api::osapi_compute_workers: {get_param: NovaWorkers}
nova::wsgi::apache_api::workers: {get_param: NovaWorkers}
service_config_settings:
rabbitmq: {get_attr: [NovaBase, role_data, service_config_settings], rabbitmq}
mysql:
map_merge:
- get_attr: [NovaApiDBClient, role_data, service_config_settings, mysql]
- get_attr: [NovaDBClient, role_data, service_config_settings, mysql]
rsyslog:
tripleo_logging_sources_nova_api:
- {get_param: NovaApiLoggingSource}
# BEGIN DOCKER SETTINGS
puppet_config:
config_volume: nova
puppet_tags: nova_config
step_config:
list_join:
- "\n"
- - "['Nova_cell_v2'].each |String $val| { noop_resource($val) }"
- include tripleo::profile::base::nova::api
- {get_attr: [MySQLClient, role_data, step_config]}
config_image: {get_param: ContainerNovaConfigImage}
kolla_config:
/var/lib/kolla/config_files/nova_api.json:
command: /usr/sbin/httpd -DFOREGROUND
config_files:
- source: "/var/lib/kolla/config_files/src/etc/httpd/conf.d"
dest: "/etc/httpd/conf.d"
merge: false
preserve_properties: true
- source: "/var/lib/kolla/config_files/src/etc/httpd/conf.modules.d"
dest: "/etc/httpd/conf.modules.d"
# TODO(emilien) remove optional flag once we get a promotion
# https://launchpad.net/bugs/1884115
optional: true
merge: false
preserve_properties: true
- source: "/var/lib/kolla/config_files/src/*"
dest: "/"
merge: true
preserve_properties: true
permissions:
- path: /var/log/nova
owner: nova:nova
recurse: true
/var/lib/kolla/config_files/nova_api_cron.json:
command: /usr/sbin/crond -n
config_files:
- source: "/var/lib/kolla/config_files/src/*"
dest: "/"
merge: true
preserve_properties: true
permissions:
- path: /var/log/nova
owner: nova:nova
recurse: true
container_config_scripts:
map_merge:
- {get_attr: [ContainersCommon, container_config_scripts]}
- nova_wait_for_api_service.py:
mode: "0755"
content: { get_file: ../../container_config_scripts/nova_wait_for_api_service.py }
nova_api_ensure_default_cell.sh:
mode: "0700"
content:
str_replace:
template: |
#!/bin/bash
DEFID=$(su nova -s /bin/bash -c "nova-manage cell_v2 list_cells" | sed -e '1,3d' -e '$d' | awk -F ' *| *' '$2 == "default" {print $4}')
if [ "$DEFID" ]; then
echo "(cellv2) Updating default cell_v2 cell $DEFID"
su nova -s /bin/bash -c "/usr/bin/nova-manage cell_v2 update_cell --cell_uuid $DEFID --name=default --database_connection='CELLDB' --transport-url='TRANSPORTURL'"
else
echo "(cellv2) Creating default cell_v2 cell"
su nova -s /bin/bash -c "/usr/bin/nova-manage cell_v2 create_cell --name=default --database_connection='CELLDB' --transport-url='TRANSPORTURL'"
fi
params:
CELLDB:
list_join:
- ''
- - '{scheme}'
- '://'
- '{username}'
- ':'
- '{password}'
- '@'
-
if:
- mysql_ipv6_use_ip_address
- '[{hostname}]'
- '{hostname}'
- '/'
- 'nova'
- '?'
- '{query}'
TRANSPORTURL:
list_join:
- ''
- - '{scheme}'
- '://'
- '{username}'
- ':'
- '{password}'
- '@'
- '{hostname}'
- ':'
- '{port}'
- '/'
- '?'
- '{query}'
docker_config:
step_2:
get_attr: [NovaApiLogging, docker_config, step_2]
step_3:
nova_api_db_sync:
start_order: 0 # Runs before nova-conductor dbsync
image: &nova_api_image {get_param: ContainerNovaApiImage}
net: host
detach: false
user: root
volumes: &nova_api_bootstrap_volumes
list_concat:
- {get_attr: [ContainersCommon, volumes]}
- {get_attr: [NovaApiLogging, volumes]}
-
- /var/lib/config-data/nova/etc/my.cnf.d/tripleo.cnf:/etc/my.cnf.d/tripleo.cnf:ro
- /var/lib/config-data/nova/etc/nova/:/etc/nova/:ro
command: "/usr/bin/bootstrap_host_exec nova_api su nova -s /bin/bash -c '/usr/bin/nova-manage api_db sync'"
environment:
TRIPLEO_DEPLOY_IDENTIFIER: {get_param: DeployIdentifier}
nova_api_map_cell0:
start_order: 1 # Runs before nova-conductor dbsync
image: *nova_api_image
net: host
detach: false
user: root
volumes: *nova_api_bootstrap_volumes
command:
str_replace:
template: "/usr/bin/bootstrap_host_exec nova_api su nova -s /bin/bash -c '/usr/bin/nova-manage cell_v2 map_cell0 --database_connection=\"CELL0DB\"'"
params:
CELL0DB:
list_join:
- ''
- - '{scheme}'
- '://'
- '{username}'
- ':'
- '{password}'
- '@'
-
if:
- mysql_ipv6_use_ip_address
- '[{hostname}]'
- '{hostname}'
- '/'
- 'nova_cell0'
- '?'
- '{query}'
nova_api_ensure_default_cell:
start_order: 2 # Runs before nova-conductor dbsync
image: *nova_api_image
net: host
detach: false
volumes:
list_concat:
- *nova_api_bootstrap_volumes
-
- /var/lib/config-data/puppet-generated/nova:/var/lib/kolla/config_files/src:ro
- /var/lib/container-config-scripts/nova_api_ensure_default_cell.sh:/nova_api_ensure_default_cell.sh:ro
user: root
command: "/usr/bin/bootstrap_host_exec nova_api /nova_api_ensure_default_cell.sh"
step_4:
nova_api:
start_order: 2
image: *nova_api_image
net: host
user: root
privileged: false
restart: always
healthcheck:
test: /openstack/healthcheck
volumes:
list_concat:
- {get_attr: [ContainersCommon, volumes]}
- {get_attr: [NovaApiLogging, volumes]}
-
- /var/lib/kolla/config_files/nova_api.json:/var/lib/kolla/config_files/config.json:ro
- /var/lib/config-data/puppet-generated/nova:/var/lib/kolla/config_files/src:ro
- if:
- internal_tls_enabled
- - /etc/pki/tls/certs/httpd:/etc/pki/tls/certs/httpd:ro
- []
- if:
- internal_tls_enabled
- - /etc/pki/tls/private/httpd:/etc/pki/tls/private/httpd:ro
- []
environment:
KOLLA_CONFIG_STRATEGY: COPY_ALWAYS
nova_wait_for_api_service:
start_order: 3
image: *nova_api_image
user: root
net: host
privileged: false
detach: false
volumes:
list_concat:
- {get_attr: [ContainersCommon, volumes]}
-
- /var/lib/config-data/nova/etc/my.cnf.d/:/etc/my.cnf.d/:ro
- /var/lib/config-data/nova/etc/nova/:/etc/nova/:ro
- /var/log/containers/nova:/var/log/nova
- /var/lib/container-config-scripts/:/container-config-scripts/:z
command: "/usr/bin/bootstrap_host_exec nova_api su nova -s /bin/bash -c '/container-config-scripts/pyshim.sh /container-config-scripts/nova_wait_for_api_service.py'"
environment:
__OS_DEBUG:
yaql:
expression: str($.data.debug)
data:
debug: {get_attr: [NovaBase, role_data, config_settings, 'nova::logging::debug']}
nova_api_cron:
start_order: 4
image: *nova_api_image
net: host
user: root
privileged: false
restart: always
healthcheck:
test: '/usr/share/openstack-tripleo-common/healthcheck/cron nova'
volumes:
list_concat:
- {get_attr: [ContainersCommon, volumes]}
- {get_attr: [NovaApiLogging, volumes]}
-
- /var/lib/kolla/config_files/nova_api_cron.json:/var/lib/kolla/config_files/config.json:ro
- /var/lib/config-data/puppet-generated/nova:/var/lib/kolla/config_files/src:ro
environment:
KOLLA_CONFIG_STRATEGY: COPY_ALWAYS
metadata_settings:
get_attr: [ApacheServiceBase, role_data, metadata_settings]
deploy_steps_tasks:
- name: validate nova-api container state
podman_container_info:
name: nova_api
register: nova_api_infos
failed_when:
- nova_api_infos.containers.0.Healthcheck.Status is defined
- "'healthy' not in nova_api_infos.containers.0.Healthcheck.Status"
retries: 10
delay: 30
tags:
- opendev-validation
- opendev-validation-nova
when:
- container_cli == 'podman'
- not container_healthcheck_disabled
- step|int == 4
host_prep_tasks: {get_attr: [NovaApiLogging, host_prep_tasks]}
external_upgrade_tasks:
- when:
- step|int == 1
tags:
- never
- system_upgrade_transfer_data
- system_upgrade_stop_services
block:
- name: Stop nova api container
import_role:
name: tripleo_container_stop
vars:
tripleo_containers_to_stop:
- nova_api
- nova_api_cron
tripleo_delegate_to: "{{ groups['nova_api'] | default([]) }}"