diff --git a/.gitignore b/.gitignore index 65e657d368..23eaabbdc2 100644 --- a/.gitignore +++ b/.gitignore @@ -70,6 +70,7 @@ common/services/compute-role.yaml common/services/controller-role.yaml common/services/objectstorage-role.yaml deployment/apache/apache-baremetal-puppet.yaml +deployment/apache/apache-baremetal-ansible.yaml deployment/container-image-prepare/container-image-prepare-baremetal-ansible.yaml deployment/haproxy/haproxy-internal-tls-certmonger.yaml deployment/octavia/octavia-deployment-config.yaml diff --git a/deployment/apache/apache-baremetal-ansible.j2.yaml b/deployment/apache/apache-baremetal-ansible.j2.yaml new file mode 100644 index 0000000000..0579580e76 --- /dev/null +++ b/deployment/apache/apache-baremetal-ansible.j2.yaml @@ -0,0 +1,211 @@ +heat_template_version: wallaby + +description: > + Apache service configured with Puppet. Note this is typically included + automatically via other services which run via Apache. + +parameters: + ApacheMaxRequestWorkers: + default: 256 + description: Maximum number of simultaneously processed requests. + type: number + ApacheServerLimit: + default: 256 + description: Maximum number of Apache processes. + type: number + 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. Use + parameter_merge_strategies to merge it with the defaults. + 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 + EndpointMap: + default: {} + description: Mapping of service endpoint -> protocol. Typically set + via parameter_defaults in the resource registry. + type: json + EnableInternalTLS: + type: boolean + default: false + InternalTLSCAFile: + default: '/etc/ipa/ca.crt' + type: string + description: Specifies the default CA cert to use if TLS is used for + services in the internal network. + CertificateKeySize: + type: string + default: '2048' + description: Specifies the private key size used when creating the + certificate. + ApacheCertificateKeySize: + type: string + default: '' + description: Override the private key size used when creating the + certificate for this service + ApacheTimeout: + type: number + default: 90 + description: The timeout in seconds for Apache, which defines duration + Apache waits for I/O operations + ApacheWSGI: + type: boolean + default: false + description: Load the WSGI module + ApacheServiceName: + type: string + default: '' + description: Service name used for the ansible parameter namespace + +conditions: + key_size_override_set: + not: {equals: [{get_param: ApacheCertificateKeySize}, '']} + +resources: + ApacheNetworks: + type: OS::Heat::Value + properties: + value: + # NOTE(xek) Get unique network names to create certificates. + # We skip the tenant and management network (vip != false) + # since we don't generate certificates for those. +{%- for role in roles %} + {{ role.name }}: + - ctlplane +{%- for network in networks if network.name in role.networks and network.enabled|default(true) and network.vip|default(false) %} + - {{network.name_lower}} +{%- endfor %} +{%- endfor %} + +outputs: + role_data: + description: Role data for the Apache role. + value: + service_name: apache + config_settings: {} + ansible_group_vars: + map_merge: + - map_replace: + - tripleo_httpd_config_httpd_conf: + TimeOut: {get_param: ApacheTimeout} + tripleo_httpd_config_prefork_serverlimit: { get_param: ApacheServerLimit } + tripleo_httpd_config_prefork_maxrequestworkers: { get_param: ApacheMaxRequestWorkers } + tripleo_httpd_config_mods: + map_merge: + - if: + - {get_param: ApacheWSGI} + - wsgi: + - so_name: 'wsgi_python3' + - if: + - {get_param: EnableInternalTLS} + - ssl: + - SSLCipherSuite: 'HIGH:MEDIUM:!aNULL:!MD5:!RC4:!3DES' + - SSLProtocol: 'all -SSLv2 -SSLv3 -TLSv1' + - SSLOptions: 'StdEnvVars' + - remoteip: + repeat: + template: + RemoteIPInternalProxy: INTERNAL_IP + for_each: + INTERNAL_IP: + get_param: + - ServiceData + - net_cidr_map + - {get_param: [ServiceNetMap, ApacheNetwork]} + - keys: + tripleo_httpd_config_httpd_conf: + str_replace: + params: + SERVICE_NAME: { get_param: ApacheServiceName } + template: + tripleo_SERVICE_NAME_httpd_config_httpd_conf + tripleo_httpd_config_prefork_serverlimit: + str_replace: + params: + SERVICE_NAME: { get_param: ApacheServiceName } + template: + tripleo_SERVICE_NAME_httpd_config_prefork_serverlimit + tripleo_httpd_config_prefork_maxrequestworkers: + str_replace: + params: + SERVICE_NAME: { get_param: ApacheServiceName } + template: + tripleo_SERVICE_NAME_httpd_config_prefork_maxrequestworkers + tripleo_httpd_config_mods: + str_replace: + params: + SERVICE_NAME: { get_param: ApacheServiceName } + template: + tripleo_SERVICE_NAME_httpd_config_mods + values: {} + - if: + - {get_param: EnableInternalTLS} + - tripleo_httpd_vhost_ssl_ca: {get_param: InternalTLSCAFile} + tripleo_httpd_config_tls_certs: + map_merge: + repeat: + template: + httpd-NETWORK: + service_certificate: '/etc/pki/tls/certs/httpd/httpd-NETWORK.crt' + service_key: '/etc/pki/tls/private/httpd/httpd-NETWORK.key' + for_each: + NETWORK: {get_attr: [ApacheNetworks, value, { get_param: RoleName }]} + metadata_settings: + if: + - {get_param: EnableInternalTLS} + - repeat: + template: + - service: HTTP + network: $NETWORK + type: node + for_each: + $NETWORK: {get_attr: [ApacheNetworks, value, { get_param: RoleName }]} + upgrade_tasks: [] + deploy_steps_tasks: + - name: Certificate generation + when: + - step|int == 1 + - enable_internal_tls + block: + - name: Create dirs for certificates and keys + file: + path: "{% raw %}{{ item }}{% endraw %}" + state: directory + serole: object_r + setype: cert_t + seuser: system_u + with_items: + - '/etc/pki/tls/certs/httpd' + - '/etc/pki/tls/private/httpd' + - include_role: + name: linux-system-roles.certificate + vars: + certificate_requests: + repeat: + template: + name: httpd-NETWORK + dns: "{% raw %}{{ fqdn_NETWORK }}{% endraw %}" + principal: "{% raw %}HTTP/{{ fqdn_NETWORK }}@{{ idm_realm }}{% endraw %}" + run_after: | + cp /etc/pki/tls/certs/httpd-NETWORK.crt /etc/pki/tls/certs/httpd/httpd-NETWORK.crt + cp /etc/pki/tls/private/httpd-NETWORK.key /etc/pki/tls/private/httpd/httpd-NETWORK.key + pkill -USR1 httpd + key_size: + if: + - key_size_override_set + - {get_param: ApacheCertificateKeySize} + - {get_param: CertificateKeySize} + ca: ipa + for_each: + NETWORK: {get_attr: [ApacheNetworks, value, { get_param: RoleName }]} diff --git a/deployment/ironic/ironic-api-container-puppet.yaml b/deployment/ironic/ironic-api-container-puppet.yaml index cd5a28b532..91f4ddc2bc 100644 --- a/deployment/ironic/ironic-api-container-puppet.yaml +++ b/deployment/ironic/ironic-api-container-puppet.yaml @@ -111,7 +111,7 @@ conditions: resources: ApacheServiceBase: - type: ../../deployment/apache/apache-baremetal-puppet.yaml + type: ../../deployment/apache/apache-baremetal-ansible.yaml properties: ServiceData: {get_param: ServiceData} ServiceNetMap: {get_param: ServiceNetMap} @@ -119,6 +119,8 @@ resources: RoleName: {get_param: RoleName} RoleParameters: {get_param: RoleParameters} EnableInternalTLS: {get_param: EnableInternalTLS} + ApacheWSGI: true + ApacheServiceName: 'ironic_api' ContainersCommon: type: ../containers-common.yaml @@ -181,14 +183,17 @@ outputs: region: {get_param: KeystoneRegion} service: 'baremetal' monitoring_subscription: {get_param: MonitoringSubscriptionIronicApi} + ansible_group_vars: + get_attr: [ApacheServiceBase, role_data, ansible_group_vars] config_settings: map_merge: - get_attr: [IronicBase, role_data, config_settings] - - get_attr: [ApacheServiceBase, role_data, config_settings] - ironic::cors::allowed_origin: if: - cors_allowed_origin_set - {get_param: IronicCorsAllowedOrigin} + tripleo::profile::base::ironic::api::configure_apache: false + ironic::api::manage_service: false ironic::api::authtoken::password: {get_param: IronicPassword} ironic::api::authtoken::project_name: 'service' ironic::api::authtoken::user_domain_name: 'Default' @@ -219,33 +224,10 @@ outputs: ironic::api::sync_db: false ironic::healthcheck::enabled: true ironic::policy::policies: {get_param: IronicApiPolicies} - ironic::wsgi::apache::vhost_custom_fragment: - if: - - auth_strategy_http_basic - - 'WSGIPassAuthorization On' - ironic::wsgi::apache::access_log_format: 'forwarded' - ironic::wsgi::apache::bind_host: - str_replace: - template: - "%{lookup('$NETWORK')}" - params: - $NETWORK: {get_param: [ServiceNetMap, IronicApiNetwork]} - ironic::wsgi::apache::servername: - str_replace: - template: - "%{lookup('fqdn_$NETWORK')}" - params: - $NETWORK: {get_param: [ServiceNetMap, IronicApiNetwork]} - ironic::wsgi::apache::ssl: {get_param: EnableInternalTLS} - ironic::wsgi::apache::workers: - if: - - ironic_workers_set - - {get_param: IronicWorkers} ironic::cors::max_age: 3600 ironic::cors::allow_methods: 'GET,POST,PUT,DELETE,OPTIONS,PATCH' ironic::cors::allow_headers: 'Content-Type,Cache-Control,Content-Language,Expires,Last-Modified,Pragma,X-Auth-Token' ironic::cors::expose_headers: 'Content-Type,Cache-Control,Content-Language,Expires,Last-Modified,Pragma' - apache::default_vhost: false # NOTE(tkajinam): the project_name parameter defaults to 'services' in puppet-ironic, # so override it here to always set the consistent project name. ironic::json_rpc::project_name: 'service' @@ -280,12 +262,12 @@ outputs: /var/lib/kolla/config_files/ironic_api.json: command: /usr/sbin/httpd -DFOREGROUND config_files: &ironic_api_config_files - - source: "/var/lib/kolla/config_files/src/etc/httpd/conf.d" - dest: "/etc/httpd/conf.d" + - source: "/var/lib/kolla/config_files/ansible/etc/httpd/conf" + dest: "/etc/httpd/conf" merge: false preserve_properties: true - - source: "/var/lib/kolla/config_files/src/etc/httpd/conf.modules.d" - dest: "/etc/httpd/conf.modules.d" + - source: "/var/lib/kolla/config_files/ansible/etc/httpd/conf.d" + dest: "/etc/httpd/conf.d" merge: false preserve_properties: true - source: "/var/lib/kolla/config_files/src/*" @@ -326,6 +308,7 @@ outputs: - - - /var/lib/kolla/config_files/ironic_api_db_sync.json:/var/lib/kolla/config_files/config.json:ro - /var/lib/config-data/puppet-generated/ironic_api:/var/lib/kolla/config_files/src:ro + - /var/lib/config-data/ansible-generated/ironic_api:/var/lib/kolla/config_files/ansible:ro - /var/log/containers/ironic:/var/log/ironic:z environment: KOLLA_CONFIG_STRATEGY: COPY_ALWAYS @@ -344,6 +327,7 @@ outputs: - {get_attr: [ContainersCommon, volumes]} - - /var/lib/kolla/config_files/ironic_api.json:/var/lib/kolla/config_files/config.json:ro - /var/lib/config-data/puppet-generated/ironic_api:/var/lib/kolla/config_files/src:ro + - /var/lib/config-data/ansible-generated/ironic_api:/var/lib/kolla/config_files/ansible:ro - /var/log/containers/ironic:/var/log/ironic:z - /var/log/containers/httpd/ironic-api:/var/log/httpd:z - if: @@ -383,8 +367,32 @@ outputs: $ADMIN_PASSWORD: {get_param: AdminPassword} $IRONIC_PASSWORD: {get_param: IronicPassword} when: is_http_basic | bool + - name: Configure vhost + vars: + map_merge: + - ironic_api_network: {get_param: [ServiceNetMap, IronicApiNetwork]} + tripleo_httpd_vhost_bind_host: "{{ lookup('vars', ironic_api_network ~ '_ip') }}" + tripleo_httpd_vhost_bind_port: {get_param: [EndpointMap, IronicInternal, port]} + tripleo_httpd_vhost_servername: "{{ lookup('vars', 'fqdn_' ~ ironic_api_network ) }}" + - if: + - auth_strategy_http_basic + - tripleo_httpd_vhost_custom_options: + {WSGIPassAuthorization: 'On'} + - if: + - {get_param: EnableInternalTLS} + - tripleo_httpd_vhost_ssl: {get_param: EnableInternalTLS} + tripleo_httpd_vhost_ssl_cert: "{{ tripleo_httpd_config_tls_certs[ironic_api_network]['service_certificate'] }}" + tripleo_httpd_vhost_ssl_key: "{{ tripleo_httpd_config_tls_certs[ironic_api_network]['service_key'] }}" + include_role: + name: tripleo_ironic + tasks_from: api_httpd.yaml deploy_steps_tasks: get_attr: [ApacheServiceBase, role_data, deploy_steps_tasks] + upgrade_tasks: + - name: Clean old httpd tree + file: + path: /var/lib/config-data/puppet-generated/ironic_api/etc/httpd + state: absent external_upgrade_tasks: - when: step|int == 1 block: &ironic_online_db_migration diff --git a/deployment/ironic/ironic-pxe-container-puppet.yaml b/deployment/ironic/ironic-pxe-container-puppet.yaml index d65c2d8805..e95176c2a8 100644 --- a/deployment/ironic/ironic-pxe-container-puppet.yaml +++ b/deployment/ironic/ironic-pxe-container-puppet.yaml @@ -37,6 +37,10 @@ parameters: default: {} description: Parameters specific to the role type: json + IronicIPXEPort: + default: 8088 + description: Port to use for serving images when iPXE is used. + type: number resources: ContainersCommon: @@ -63,6 +67,7 @@ outputs: service_name: ironic_pxe config_settings: ironic::pxe::tftp_use_xinetd: false + ironic::pxe::manage_http_server: false service_config_settings: {} # BEGIN DOCKER SETTINGS puppet_config: @@ -74,12 +79,12 @@ outputs: /var/lib/kolla/config_files/ironic_pxe_http.json: command: /usr/sbin/httpd -DFOREGROUND config_files: - - source: "/var/lib/kolla/config_files/src/etc/httpd/conf.d" + - source: "/var/lib/kolla/config_files/ansible/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" + - source: "/var/lib/kolla/config_files/ansible/etc/httpd/conf" + dest: "/etc/httpd/conf" merge: false preserve_properties: true - source: "/var/lib/kolla/config_files/src/*" @@ -131,6 +136,10 @@ outputs: - name: Set fact ironic_pxe_tftp_enabled set_fact: ironic_pxe_tftp_enabled: "{{ ironic_pxe_tftp_enabled_result.rc == 0 }}" + - name: Clean old httpd tree + file: + path: /var/lib/config-data/puppet-generated/ironic/etc/httpd + state: absent - name: Stop ironic_pxe_tftp service when: - step|int == 1 @@ -156,6 +165,7 @@ outputs: - {get_attr: [ContainersCommon, volumes]} - - /var/lib/kolla/config_files/ironic_pxe_tftp.json:/var/lib/kolla/config_files/config.json:ro - /var/lib/config-data/puppet-generated/ironic:/var/lib/kolla/config_files/src:ro + - /var/lib/config-data/ansible-generated/ironic:/var/lib/kolla/config_files/ansible:ro - /var/lib/ironic:/var/lib/ironic:shared,z - /var/log/containers/ironic:/var/log/ironic:z - /var/log/containers/httpd/ironic-pxe:/var/log/httpd:z @@ -174,6 +184,7 @@ outputs: - {get_attr: [ContainersCommon, volumes]} - - /var/lib/kolla/config_files/ironic_pxe_http.json:/var/lib/kolla/config_files/config.json:ro - /var/lib/config-data/puppet-generated/ironic:/var/lib/kolla/config_files/src:ro + - /var/lib/config-data/ansible-generated/ironic:/var/lib/kolla/config_files/ansible:ro - /var/lib/ironic:/var/lib/ironic:shared,z - /var/log/containers/ironic:/var/log/ironic:z - /var/log/containers/httpd/ironic-pxe:/var/log/httpd:z @@ -190,6 +201,14 @@ outputs: - { 'path': /var/lib/ironic, 'setype': container_file_t, 'mode': 'g+s' } - { 'path': /var/log/containers/ironic, 'setype': container_file_t, 'mode': '0750' } - { 'path': /var/log/containers/httpd/ironic-pxe, 'setype': container_file_t, 'mode': '0750' } + - name: Create vhost for ipxe + vars: + ironic_ipxe_network: {get_param: [ServiceNetMap, IronicNetwork] } + tripleo_httpd_vhost_bind_host: "{{ lookup('vars', ironic_ipxe_network ~ '_ip') }}" + tripleo_httpd_vhost_bind_port: {get_param: IronicIPXEPort} + import_role: + name: tripleo_ironic + tasks_from: ipxe_httpd.yaml external_upgrade_tasks: - when: - step|int == 1