From 885bf88174921ba1ee4852caa8c1034430a51ca1 Mon Sep 17 00:00:00 2001 From: Oliver Walsh Date: Fri, 24 Mar 2017 14:35:09 +0000 Subject: [PATCH] SSH known_hosts config Fetch the host public keys from each node, combine them all and write to the system-wide ssh known hosts. The alternative of disabling host key verification is vulnerable to a MITM attack. Change-Id: Ib572b5910720b1991812256e68c975f7fbe2239c (cherry picked from commit 7d3552a105ad5aa62cad0998c11df5ec6bd06ed6) --- extraconfig/tasks/ssh/host_public_key.yaml | 42 ++++++++++++ extraconfig/tasks/ssh/known_hosts_config.yaml | 36 ++++++++++ overcloud-resource-registry-puppet.j2.yaml | 2 + overcloud.j2.yaml | 17 +++++ puppet/blockstorage-role.yaml | 65 +++++++++++++++++++ puppet/cephstorage-role.yaml | 65 +++++++++++++++++++ puppet/compute-role.yaml | 65 +++++++++++++++++++ puppet/controller-role.yaml | 65 +++++++++++++++++++ puppet/objectstorage-role.yaml | 65 +++++++++++++++++++ puppet/role.role.j2.yaml | 65 +++++++++++++++++++ .../ssh_known_hosts-287563590632d1aa.yaml | 4 ++ 11 files changed, 491 insertions(+) create mode 100644 extraconfig/tasks/ssh/host_public_key.yaml create mode 100644 extraconfig/tasks/ssh/known_hosts_config.yaml create mode 100644 releasenotes/notes/ssh_known_hosts-287563590632d1aa.yaml diff --git a/extraconfig/tasks/ssh/host_public_key.yaml b/extraconfig/tasks/ssh/host_public_key.yaml new file mode 100644 index 0000000000..afbac55f15 --- /dev/null +++ b/extraconfig/tasks/ssh/host_public_key.yaml @@ -0,0 +1,42 @@ +heat_template_version: 2016-10-14 + +description: > + This is a template which will fetch the ssh host public key. + +parameters: + server: + description: ID of the node to apply this config to + type: string + +resources: + SshHostPubKeyConfig: + type: OS::Heat::SoftwareConfig + properties: + group: script + outputs: + - name: rsa + - name: ecdsa + - name: ed25519 + config: | + #!/bin/sh -x + test -e '/etc/ssh/ssh_host_rsa_key.pub' && cat /etc/ssh/ssh_host_rsa_key.pub > $heat_outputs_path.rsa + test -e '/etc/ssh/ssh_host_ecdsa_key.pub' && cat /etc/ssh/ssh_host_ecdsa_key.pub > $heat_outputs_path.ecdsa + test -e '/etc/ssh/ssh_host_ed25519_key.pub' && cat /etc/ssh/ssh_host_ed25519_key.pub > $heat_outputs_path.ed25519 + + SshHostPubKeyDeployment: + type: OS::Heat::SoftwareDeployment + properties: + config: {get_resource: SshHostPubKeyConfig} + server: {get_param: server} + + +outputs: + ecdsa: + description: Host ssh public key (ecdsa) + value: {get_attr: [SshHostPubKeyDeployment, ecdsa]} + rsa: + description: Host ssh public key (rsa) + value: {get_attr: [SshHostPubKeyDeployment, rsa]} + ed25519: + description: Host ssh public key (ed25519) + value: {get_attr: [SshHostPubKeyDeployment, ed25519]} diff --git a/extraconfig/tasks/ssh/known_hosts_config.yaml b/extraconfig/tasks/ssh/known_hosts_config.yaml new file mode 100644 index 0000000000..49a04e0495 --- /dev/null +++ b/extraconfig/tasks/ssh/known_hosts_config.yaml @@ -0,0 +1,36 @@ +heat_template_version: 2016-10-14 +description: 'SSH Known Hosts Config' + +parameters: + known_hosts: + type: string + +resources: + + SSHKnownHostsConfig: + type: OS::Heat::SoftwareConfig + properties: + group: script + inputs: + - name: known_hosts + default: {get_param: known_hosts} + config: | + #!/bin/bash + set -eux + set -o pipefail + + echo "Creating ssh known hosts file" + + if [ ! -z "${known_hosts}" ]; then + echo "${known_hosts}" + echo -ne "${known_hosts}" > /etc/ssh/ssh_known_hosts + chmod 0644 /etc/ssh/ssh_known_hosts + else + rm -f /etc/ssh/ssh_known_hosts + echo "No ssh known hosts" + fi + +outputs: + OS::stack_id: + description: The SSHKnownHostsConfig resource. + value: {get_resource: SSHKnownHostsConfig} diff --git a/overcloud-resource-registry-puppet.j2.yaml b/overcloud-resource-registry-puppet.j2.yaml index c46668a42a..3237a50bc2 100644 --- a/overcloud-resource-registry-puppet.j2.yaml +++ b/overcloud-resource-registry-puppet.j2.yaml @@ -4,6 +4,8 @@ resource_registry: OS::TripleO::PostDeploySteps: puppet/post.yaml OS::TripleO::AllNodes::SoftwareConfig: puppet/all-nodes-config.yaml OS::TripleO::Hosts::SoftwareConfig: hosts-config.yaml + OS::TripleO::Ssh::HostPubKey: extraconfig/tasks/ssh/host_public_key.yaml + OS::TripleO::Ssh::KnownHostsConfig: extraconfig/tasks/ssh/known_hosts_config.yaml OS::TripleO::DefaultPasswords: default_passwords.yaml # Tasks (for internal TripleO usage) diff --git a/overcloud.j2.yaml b/overcloud.j2.yaml index 15bcfb63c3..20c2b120c4 100644 --- a/overcloud.j2.yaml +++ b/overcloud.j2.yaml @@ -201,6 +201,16 @@ resources: NetIpMap: {get_attr: [VipMap, net_ip_map]} ServiceNetMap: {get_attr: [ServiceNetMap, service_net_map]} + SshKnownHostsConfig: + type: OS::TripleO::Ssh::KnownHostsConfig + properties: + known_hosts: + list_join: + - '' + {% for role in roles %} + - {get_attr: [{{role.name}}, known_hosts_entry]} + {% endfor %} + # Jinja loop for Role in roles_data.yaml {% for role in roles %} # Resources generated for {{role.name}} Role @@ -220,6 +230,13 @@ resources: config: {get_attr: [hostsConfig, config_id]} servers: {get_attr: [{{role.name}}, attributes, nova_server_resource]} + {{role.name}}SshKnownHostsDeployment: + type: OS::Heat::StructuredDeployments + properties: + name: {{role.name}}SshKnownHostsDeployment + config: {get_resource: SshKnownHostsConfig} + servers: {get_attr: [{{role.name}}, attributes, nova_server_resource]} + {{role.name}}AllNodesDeployment: type: OS::Heat::StructuredDeployments depends_on: diff --git a/puppet/blockstorage-role.yaml b/puppet/blockstorage-role.yaml index 34f10a21be..e35c7161dc 100644 --- a/puppet/blockstorage-role.yaml +++ b/puppet/blockstorage-role.yaml @@ -301,6 +301,12 @@ resources: update_identifier: get_param: UpdateIdentifier + SshHostPubKey: + type: OS::TripleO::Ssh::HostPubKey + depends_on: BlockStorageDeployment + properties: + server: {get_resource: BlockStorage} + outputs: ip_address: description: IP address of the server in the ctlplane network @@ -411,6 +417,65 @@ outputs: - '.' - - {get_attr: [BlockStorage, name]} - ctlplane + known_hosts_entry: + description: Entry for ssh known hosts + value: + str_replace: + template: "PRIMARYIP,PRIMARYHOST.DOMAIN,PRIMARYHOST,\ +EXTERNALIP,EXTERNALHOST.DOMAIN,EXTERNALHOST,\ +INTERNAL_APIIP,INTERNAL_APIHOST.DOMAIN,INTERNAL_APIHOST,\ +STORAGEIP,STORAGEHOST.DOMAIN,STORAGEHOST,\ +STORAGE_MGMTIP,STORAGE_MGMTHOST.DOMAIN,STORAGE_MGMTHOST,\ +TENANTIP,TENANTHOST.DOMAIN,TENANTHOST,\ +MANAGEMENTIP,MANAGEMENTHOST.DOMAIN,MANAGEMENTHOST,\ +CTLPLANEIP,CTLPLANEHOST.DOMAIN,CTLPLANEHOST HOSTSSHPUBKEY" + params: + PRIMARYIP: {get_attr: [NetIpMap, net_ip_map, {get_param: [ServiceNetMap, BlockStorageHostnameResolveNetwork]}]} + DOMAIN: {get_param: CloudDomain} + PRIMARYHOST: {get_attr: [BlockStorage, name]} + EXTERNALIP: {get_attr: [ExternalPort, ip_address]} + EXTERNALHOST: + list_join: + - '.' + - - {get_attr: [BlockStorage, name]} + - external + INTERNAL_APIIP: {get_attr: [InternalApiPort, ip_address]} + INTERNAL_APIHOST: + list_join: + - '.' + - - {get_attr: [BlockStorage, name]} + - internalapi + STORAGEIP: {get_attr: [StoragePort, ip_address]} + STORAGEHOST: + list_join: + - '.' + - - {get_attr: [BlockStorage, name]} + - storage + STORAGE_MGMTIP: {get_attr: [StorageMgmtPort, ip_address]} + STORAGE_MGMTHOST: + list_join: + - '.' + - - {get_attr: [BlockStorage, name]} + - storagemgmt + TENANTIP: {get_attr: [TenantPort, ip_address]} + TENANTHOST: + list_join: + - '.' + - - {get_attr: [BlockStorage, name]} + - tenant + MANAGEMENTIP: {get_attr: [ManagementPort, ip_address]} + MANAGEMENTHOST: + list_join: + - '.' + - - {get_attr: [BlockStorage, name]} + - management + CTLPLANEIP: {get_attr: [BlockStorage, networks, ctlplane, 0]} + CTLPLANEHOST: + list_join: + - '.' + - - {get_attr: [BlockStorage, name]} + - ctlplane + HOSTSSHPUBKEY: {get_attr: [SshHostPubKey, ecdsa]} nova_server_resource: description: Heat resource handle for the block storage server value: diff --git a/puppet/cephstorage-role.yaml b/puppet/cephstorage-role.yaml index 0854330ec5..e63b60b7c5 100644 --- a/puppet/cephstorage-role.yaml +++ b/puppet/cephstorage-role.yaml @@ -312,6 +312,12 @@ resources: update_identifier: get_param: UpdateIdentifier + SshHostPubKey: + type: OS::TripleO::Ssh::HostPubKey + depends_on: CephStorageDeployment + properties: + server: {get_resource: CephStorage} + outputs: ip_address: description: IP address of the server in the ctlplane network @@ -422,6 +428,65 @@ outputs: - '.' - - {get_attr: [CephStorage, name]} - ctlplane + known_hosts_entry: + description: Entry for ssh known hosts + value: + str_replace: + template: "PRIMARYIP,PRIMARYHOST.DOMAIN,PRIMARYHOST,\ +EXTERNALIP,EXTERNALHOST.DOMAIN,EXTERNALHOST,\ +INTERNAL_APIIP,INTERNAL_APIHOST.DOMAIN,INTERNAL_APIHOST,\ +STORAGEIP,STORAGEHOST.DOMAIN,STORAGEHOST,\ +STORAGE_MGMTIP,STORAGE_MGMTHOST.DOMAIN,STORAGE_MGMTHOST,\ +TENANTIP,TENANTHOST.DOMAIN,TENANTHOST,\ +MANAGEMENTIP,MANAGEMENTHOST.DOMAIN,MANAGEMENTHOST,\ +CTLPLANEIP,CTLPLANEHOST.DOMAIN,CTLPLANEHOST HOSTSSHPUBKEY" + params: + PRIMARYIP: {get_attr: [NetIpMap, net_ip_map, {get_param: [ServiceNetMap, CephStorageHostnameResolveNetwork]}]} + DOMAIN: {get_param: CloudDomain} + PRIMARYHOST: {get_attr: [CephStorage, name]} + EXTERNALIP: {get_attr: [ExternalPort, ip_address]} + EXTERNALHOST: + list_join: + - '.' + - - {get_attr: [CephStorage, name]} + - external + INTERNAL_APIIP: {get_attr: [InternalApiPort, ip_address]} + INTERNAL_APIHOST: + list_join: + - '.' + - - {get_attr: [CephStorage, name]} + - internalapi + STORAGEIP: {get_attr: [StoragePort, ip_address]} + STORAGEHOST: + list_join: + - '.' + - - {get_attr: [CephStorage, name]} + - storage + STORAGE_MGMTIP: {get_attr: [StorageMgmtPort, ip_address]} + STORAGE_MGMTHOST: + list_join: + - '.' + - - {get_attr: [CephStorage, name]} + - storagemgmt + TENANTIP: {get_attr: [TenantPort, ip_address]} + TENANTHOST: + list_join: + - '.' + - - {get_attr: [CephStorage, name]} + - tenant + MANAGEMENTIP: {get_attr: [ManagementPort, ip_address]} + MANAGEMENTHOST: + list_join: + - '.' + - - {get_attr: [CephStorage, name]} + - management + CTLPLANEIP: {get_attr: [CephStorage, networks, ctlplane, 0]} + CTLPLANEHOST: + list_join: + - '.' + - - {get_attr: [CephStorage, name]} + - ctlplane + HOSTSSHPUBKEY: {get_attr: [SshHostPubKey, ecdsa]} nova_server_resource: description: Heat resource handle for the ceph storage server value: diff --git a/puppet/compute-role.yaml b/puppet/compute-role.yaml index 070f19c59f..1bc4d1ef0f 100644 --- a/puppet/compute-role.yaml +++ b/puppet/compute-role.yaml @@ -336,6 +336,12 @@ resources: update_identifier: get_param: UpdateIdentifier + SshHostPubKey: + type: OS::TripleO::Ssh::HostPubKey + depends_on: NovaComputeDeployment + properties: + server: {get_resource: NovaCompute} + outputs: ip_address: description: IP address of the server in the ctlplane network @@ -466,6 +472,65 @@ outputs: - '.' - - {get_attr: [NovaCompute, name]} - ctlplane + known_hosts_entry: + description: Entry for ssh known hosts + value: + str_replace: + template: "PRIMARYIP,PRIMARYHOST.DOMAIN,PRIMARYHOST,\ +EXTERNALIP,EXTERNALHOST.DOMAIN,EXTERNALHOST,\ +INTERNAL_APIIP,INTERNAL_APIHOST.DOMAIN,INTERNAL_APIHOST,\ +STORAGEIP,STORAGEHOST.DOMAIN,STORAGEHOST,\ +STORAGE_MGMTIP,STORAGE_MGMTHOST.DOMAIN,STORAGE_MGMTHOST,\ +TENANTIP,TENANTHOST.DOMAIN,TENANTHOST,\ +MANAGEMENTIP,MANAGEMENTHOST.DOMAIN,MANAGEMENTHOST,\ +CTLPLANEIP,CTLPLANEHOST.DOMAIN,CTLPLANEHOST HOSTSSHPUBKEY" + params: + HOSTSSHPUBKEY: {get_attr: [SshHostPubKey, ecdsa]} + PRIMARYIP: {get_attr: [NetIpMap, net_ip_map, {get_param: [ServiceNetMap, ComputeHostnameResolveNetwork]}]} + DOMAIN: {get_param: CloudDomain} + PRIMARYHOST: {get_attr: [NovaCompute, name]} + EXTERNALIP: {get_attr: [ExternalPort, ip_address]} + EXTERNALHOST: + list_join: + - '.' + - - {get_attr: [NovaCompute, name]} + - external + INTERNAL_APIIP: {get_attr: [InternalApiPort, ip_address]} + INTERNAL_APIHOST: + list_join: + - '.' + - - {get_attr: [NovaCompute, name]} + - internalapi + STORAGEIP: {get_attr: [StoragePort, ip_address]} + STORAGEHOST: + list_join: + - '.' + - - {get_attr: [NovaCompute, name]} + - storage + STORAGE_MGMTIP: {get_attr: [StorageMgmtPort, ip_address]} + STORAGE_MGMTHOST: + list_join: + - '.' + - - {get_attr: [NovaCompute, name]} + - storagemgmt + TENANTIP: {get_attr: [TenantPort, ip_address]} + TENANTHOST: + list_join: + - '.' + - - {get_attr: [NovaCompute, name]} + - tenant + MANAGEMENTIP: {get_attr: [ManagementPort, ip_address]} + MANAGEMENTHOST: + list_join: + - '.' + - - {get_attr: [NovaCompute, name]} + - management + CTLPLANEIP: {get_attr: [NovaCompute, networks, ctlplane, 0]} + CTLPLANEHOST: + list_join: + - '.' + - - {get_attr: [NovaCompute, name]} + - ctlplane nova_server_resource: description: Heat resource handle for the Nova compute server value: diff --git a/puppet/controller-role.yaml b/puppet/controller-role.yaml index 3fc691a0e5..f305145fb9 100644 --- a/puppet/controller-role.yaml +++ b/puppet/controller-role.yaml @@ -379,6 +379,12 @@ resources: update_identifier: get_param: UpdateIdentifier + SshHostPubKey: + type: OS::TripleO::Ssh::HostPubKey + depends_on: ControllerDeployment + properties: + server: {get_resource: Controller} + outputs: ip_address: description: IP address of the server in the ctlplane network @@ -509,6 +515,65 @@ outputs: - '.' - - {get_attr: [Controller, name]} - ctlplane + known_hosts_entry: + description: Entry for ssh known hosts + value: + str_replace: + template: "PRIMARYIP,PRIMARYHOST.DOMAIN,PRIMARYHOST,\ +EXTERNALIP,EXTERNALHOST.DOMAIN,EXTERNALHOST,\ +INTERNAL_APIIP,INTERNAL_APIHOST.DOMAIN,INTERNAL_APIHOST,\ +STORAGEIP,STORAGEHOST.DOMAIN,STORAGEHOST,\ +STORAGE_MGMTIP,STORAGE_MGMTHOST.DOMAIN,STORAGE_MGMTHOST,\ +TENANTIP,TENANTHOST.DOMAIN,TENANTHOST,\ +MANAGEMENTIP,MANAGEMENTHOST.DOMAIN,MANAGEMENTHOST,\ +CTLPLANEIP,CTLPLANEHOST.DOMAIN,CTLPLANEHOST HOSTSSHPUBKEY" + params: + PRIMARYIP: {get_attr: [NetIpMap, net_ip_map, {get_param: [ServiceNetMap, ControllerHostnameResolveNetwork]}]} + DOMAIN: {get_param: CloudDomain} + PRIMARYHOST: {get_attr: [Controller, name]} + EXTERNALIP: {get_attr: [ExternalPort, ip_address]} + EXTERNALHOST: + list_join: + - '.' + - - {get_attr: [Controller, name]} + - external + INTERNAL_APIIP: {get_attr: [InternalApiPort, ip_address]} + INTERNAL_APIHOST: + list_join: + - '.' + - - {get_attr: [Controller, name]} + - internalapi + STORAGEIP: {get_attr: [StoragePort, ip_address]} + STORAGEHOST: + list_join: + - '.' + - - {get_attr: [Controller, name]} + - storage + STORAGE_MGMTIP: {get_attr: [StorageMgmtPort, ip_address]} + STORAGE_MGMTHOST: + list_join: + - '.' + - - {get_attr: [Controller, name]} + - storagemgmt + TENANTIP: {get_attr: [TenantPort, ip_address]} + TENANTHOST: + list_join: + - '.' + - - {get_attr: [Controller, name]} + - tenant + MANAGEMENTIP: {get_attr: [ManagementPort, ip_address]} + MANAGEMENTHOST: + list_join: + - '.' + - - {get_attr: [Controller, name]} + - management + CTLPLANEIP: {get_attr: [Controller, networks, ctlplane, 0]} + CTLPLANEHOST: + list_join: + - '.' + - - {get_attr: [Controller, name]} + - ctlplane + HOSTSSHPUBKEY: {get_attr: [SshHostPubKey, ecdsa]} nova_server_resource: description: Heat resource handle for the Nova compute server value: diff --git a/puppet/objectstorage-role.yaml b/puppet/objectstorage-role.yaml index be638c5619..53a4b0488b 100644 --- a/puppet/objectstorage-role.yaml +++ b/puppet/objectstorage-role.yaml @@ -300,6 +300,12 @@ resources: update_identifier: get_param: UpdateIdentifier + SshHostPubKey: + type: OS::TripleO::Ssh::HostPubKey + depends_on: SwiftStorageHieraDeploy + properties: + server: {get_resource: SwiftStorage} + outputs: ip_address: description: IP address of the server in the ctlplane network @@ -410,6 +416,65 @@ outputs: - '.' - - {get_attr: [SwiftStorage, name]} - ctlplane + known_hosts_entry: + description: Entry for ssh known hosts + value: + str_replace: + template: "PRIMARYIP,PRIMARYHOST.DOMAIN,PRIMARYHOST,\ +EXTERNALIP,EXTERNALHOST.DOMAIN,EXTERNALHOST,\ +INTERNAL_APIIP,INTERNAL_APIHOST.DOMAIN,INTERNAL_APIHOST,\ +STORAGEIP,STORAGEHOST.DOMAIN,STORAGEHOST,\ +STORAGE_MGMTIP,STORAGE_MGMTHOST.DOMAIN,STORAGE_MGMTHOST,\ +TENANTIP,TENANTHOST.DOMAIN,TENANTHOST,\ +MANAGEMENTIP,MANAGEMENTHOST.DOMAIN,MANAGEMENTHOST,\ +CTLPLANEIP,CTLPLANEHOST.DOMAIN,CTLPLANEHOST HOSTSSHPUBKEY" + params: + PRIMARYIP: {get_attr: [NetIpMap, net_ip_map, {get_param: [ServiceNetMap, ObjectStorageHostnameResolveNetwork]}]} + DOMAIN: {get_param: CloudDomain} + PRIMARYHOST: {get_attr: [SwiftStorage, name]} + EXTERNALIP: {get_attr: [ExternalPort, ip_address]} + EXTERNALHOST: + list_join: + - '.' + - - {get_attr: [SwiftStorage, name]} + - external + INTERNAL_APIIP: {get_attr: [InternalApiPort, ip_address]} + INTERNAL_APIHOST: + list_join: + - '.' + - - {get_attr: [SwiftStorage, name]} + - internalapi + STORAGEIP: {get_attr: [StoragePort, ip_address]} + STORAGEHOST: + list_join: + - '.' + - - {get_attr: [SwiftStorage, name]} + - storage + STORAGE_MGMTIP: {get_attr: [StorageMgmtPort, ip_address]} + STORAGE_MGMTHOST: + list_join: + - '.' + - - {get_attr: [SwiftStorage, name]} + - storagemgmt + TENANTIP: {get_attr: [TenantPort, ip_address]} + TENANTHOST: + list_join: + - '.' + - - {get_attr: [SwiftStorage, name]} + - tenant + MANAGEMENTIP: {get_attr: [ManagementPort, ip_address]} + MANAGEMENTHOST: + list_join: + - '.' + - - {get_attr: [SwiftStorage, name]} + - management + CTLPLANEIP: {get_attr: [SwiftStorage, networks, ctlplane, 0]} + CTLPLANEHOST: + list_join: + - '.' + - - {get_attr: [SwiftStorage, name]} + - ctlplane + HOSTSSHPUBKEY: {get_attr: [SshHostPubKey, ecdsa]} nova_server_resource: description: Heat resource handle for the swift storage server value: diff --git a/puppet/role.role.j2.yaml b/puppet/role.role.j2.yaml index cbe3c80016..28103f4811 100644 --- a/puppet/role.role.j2.yaml +++ b/puppet/role.role.j2.yaml @@ -327,6 +327,12 @@ resources: update_identifier: get_param: UpdateIdentifier + SshHostPubKey: + type: OS::TripleO::Ssh::HostPubKey + depends_on: {{role}}Deployment + properties: + server: {get_resource: {{role}}} + outputs: ip_address: description: IP address of the server in the ctlplane network @@ -437,6 +443,65 @@ outputs: - '.' - - {get_attr: [{{role}}, name]} - ctlplane + known_hosts_entry: + description: Entry for ssh known hosts + value: + str_replace: + template: "PRIMARYIP,PRIMARYHOST.DOMAIN,PRIMARYHOST,\ +EXTERNALIP,EXTERNALHOST.DOMAIN,EXTERNALHOST,\ +INTERNAL_APIIP,INTERNAL_APIHOST.DOMAIN,INTERNAL_APIHOST,\ +STORAGEIP,STORAGEHOST.DOMAIN,STORAGEHOST,\ +STORAGE_MGMTIP,STORAGE_MGMTHOST.DOMAIN,STORAGE_MGMTHOST,\ +TENANTIP,TENANTHOST.DOMAIN,TENANTHOST,\ +MANAGEMENTIP,MANAGEMENTHOST.DOMAIN,MANAGEMENTHOST,\ +CTLPLANEIP,CTLPLANEHOST.DOMAIN,CTLPLANEHOST HOSTSSHPUBKEY" + params: + PRIMARYIP: {get_attr: [NetIpMap, net_ip_map, {get_param: [ServiceNetMap, {{role}}HostnameResolveNetwork]}]} + DOMAIN: {get_param: CloudDomain} + PRIMARYHOST: {get_attr: [{{role}}, name]} + EXTERNALIP: {get_attr: [ExternalPort, ip_address]} + EXTERNALHOST: + list_join: + - '.' + - - {get_attr: [{{role}}, name]} + - external + INTERNAL_APIIP: {get_attr: [InternalApiPort, ip_address]} + INTERNAL_APIHOST: + list_join: + - '.' + - - {get_attr: [{{role}}, name]} + - internalapi + STORAGEIP: {get_attr: [StoragePort, ip_address]} + STORAGEHOST: + list_join: + - '.' + - - {get_attr: [{{role}}, name]} + - storage + STORAGE_MGMTIP: {get_attr: [StorageMgmtPort, ip_address]} + STORAGE_MGMTHOST: + list_join: + - '.' + - - {get_attr: [{{role}}, name]} + - storagemgmt + TENANTIP: {get_attr: [TenantPort, ip_address]} + TENANTHOST: + list_join: + - '.' + - - {get_attr: [{{role}}, name]} + - tenant + MANAGEMENTIP: {get_attr: [ManagementPort, ip_address]} + MANAGEMENTHOST: + list_join: + - '.' + - - {get_attr: [{{role}}, name]} + - management + CTLPLANEIP: {get_attr: [{{role}}, networks, ctlplane, 0]} + CTLPLANEHOST: + list_join: + - '.' + - - {get_attr: [{{role}}, name]} + - ctlplane + HOSTSSHPUBKEY: {get_attr: [SshHostPubKey, ecdsa]} nova_server_resource: description: Heat resource handle for {{role}} server value: diff --git a/releasenotes/notes/ssh_known_hosts-287563590632d1aa.yaml b/releasenotes/notes/ssh_known_hosts-287563590632d1aa.yaml new file mode 100644 index 0000000000..8b533b1ab9 --- /dev/null +++ b/releasenotes/notes/ssh_known_hosts-287563590632d1aa.yaml @@ -0,0 +1,4 @@ +--- +features: + - SSH host key exchange. The ssh host keys are collected from each host, + combined, and written to /etc/ssh/ssh_known_hosts.