Merge "Add services to ServiceNetMap to select hostnames resolution network"
[apex-tripleo-heat-templates.git] / puppet / controller-puppet.yaml
1 heat_template_version: 2015-04-30
2
3 description: >
4   OpenStack controller node configured by Puppet.
5
6 parameters:
7   AdminPassword:
8     default: unset
9     description: The password for the keystone admin account, used for monitoring, querying neutron etc.
10     type: string
11     hidden: true
12   AdminToken:
13     default: unset
14     description: The keystone auth secret and db password.
15     type: string
16     hidden: true
17   CeilometerBackend:
18     default: 'mongodb'
19     description: The ceilometer backend type.
20     type: string
21   CeilometerMeteringSecret:
22     default: unset
23     description: Secret shared by the ceilometer services.
24     type: string
25     hidden: true
26   CeilometerPassword:
27     default: unset
28     description: The password for the ceilometer service  and db account.
29     type: string
30     hidden: true
31   CinderEnableIscsiBackend:
32     default: true
33     description: Whether to enable or not the Iscsi backend for Cinder
34     type: boolean
35   CinderEnableRbdBackend:
36     default: false
37     description: Whether to enable or not the Rbd backend for Cinder
38     type: boolean
39   CinderISCSIHelper:
40     default: tgtadm
41     description: The iSCSI helper to use with cinder.
42     type: string
43   CinderLVMLoopDeviceSize:
44     default: 5000
45     description: The size of the loopback file used by the cinder LVM driver.
46     type: number
47   CinderPassword:
48     default: unset
49     description: The password for the cinder service and db account, used by cinder-api.
50     type: string
51     hidden: true
52   CinderBackendConfig:
53     default: {}
54     description: Contains parameters to configure Cinder backends. Typically
55                  set via parameter_defaults in the resource registry.
56     type: json
57   CloudName:
58     default: ''
59     description: The DNS name of this cloud. E.g. ci-overcloud.tripleo.org
60     type: string
61   ControllerExtraConfig:
62     default: {}
63     description: |
64       Controller specific configuration to inject into the cluster. Same
65       structure as ExtraConfig.
66     type: json
67   ControlVirtualInterface:
68     default: 'br-ex'
69     description: Interface where virtual ip will be assigned.
70     type: string
71   Debug:
72     default: ''
73     description: Set to True to enable debugging on all services.
74     type: string
75   EnableFencing:
76     default: false
77     description: Whether to enable fencing in Pacemaker or not.
78     type: boolean
79   EnableGalera:
80     default: true
81     description: Whether to use Galera instead of regular MariaDB.
82     type: boolean
83   EnableCephStorage:
84     default: false
85     description: Whether to deploy Ceph Storage (OSD) on the Controller
86     type: boolean
87   EnableSwiftStorage:
88     default: true
89     description: Whether to enable Swift Storage on the Controller
90     type: boolean
91   ExtraConfig:
92     default: {}
93     description: |
94       Additional configuration to inject into the cluster. The JSON should have
95       the following structure:
96         {"FILEKEY":
97           {"config":
98             [{"section": "SECTIONNAME",
99               "values":
100                 [{"option": "OPTIONNAME",
101                   "value": "VALUENAME"
102                  }
103                 ]
104              }
105             ]
106           }
107         }
108       For instance:
109         {"nova":
110           {"config":
111             [{"section": "default",
112               "values":
113                 [{"option": "compute_manager",
114                   "value": "ironic.nova.compute.manager.ClusterComputeManager"
115                  }
116                 ]
117              },
118              {"section": "cells",
119               "values":
120                 [{"option": "driver",
121                   "value": "nova.cells.rpc_driver.CellsRPCDriver"
122                  }
123                 ]
124              }
125             ]
126           }
127         }
128     type: json
129   FencingConfig:
130     default: {}
131     description: |
132       Pacemaker fencing configuration. The JSON should have
133       the following structure:
134         {
135           "devices": [
136             {
137               "agent": "AGENT_NAME",
138               "host_mac": "HOST_MAC_ADDRESS",
139               "params": {"PARAM_NAME": "PARAM_VALUE"}
140             }
141           ]
142         }
143       For instance:
144         {
145           "devices": [
146             {
147               "agent": "fence_xvm",
148               "host_mac": "52:54:00:aa:bb:cc",
149               "params": {
150                 "multicast_address": "225.0.0.12",
151                 "port": "baremetal_0",
152                 "manage_fw": true,
153                 "manage_key_file": true,
154                 "key_file": "/etc/fence_xvm.key",
155                 "key_file_password": "abcdef"
156               }
157             }
158           ]
159         }
160     type: json
161   Flavor:
162     description: Flavor for control nodes to request when deploying.
163     type: string
164     constraints:
165       - custom_constraint: nova.flavor
166   GlanceNotifierStrategy:
167     description: Strategy to use for Glance notification queue
168     type: string
169     default: noop
170   GlanceLogFile:
171     description: The filepath of the file to use for logging messages from Glance.
172     type: string
173     default: ''
174   GlancePassword:
175     default: unset
176     description: The password for the glance service and db account, used by the glance services.
177     type: string
178     hidden: true
179   GlancePort:
180     default: "9292"
181     description: Glance port.
182     type: string
183   GlanceProtocol:
184     default: http
185     description: Protocol to use when connecting to glance, set to https for SSL.
186     type: string
187   GlanceBackend:
188     default: swift
189     description: The short name of the Glance backend to use. Should be one
190       of swift, rbd, or file
191     type: string
192     constraints:
193     - allowed_values: ['swift', 'file', 'rbd']
194   HeatPassword:
195     default: unset
196     description: The password for the Heat service and db account, used by the Heat services.
197     type: string
198     hidden: true
199   HeatStackDomainAdminPassword:
200     description: Password for heat_domain_admin user.
201     type: string
202     default: ''
203     hidden: true
204   HeatAuthEncryptionKey:
205     description: Auth encryption key for heat-engine
206     type: string
207   HorizonSecret:
208     description: Secret key for Django
209     type: string
210   Image:
211     type: string
212     default: overcloud-control
213     constraints:
214       - custom_constraint: glance.image
215   ImageUpdatePolicy:
216     default: 'REBUILD_PRESERVE_EPHEMERAL'
217     description: What policy to use when reconstructing instances. REBUILD for rebuilds, REBUILD_PRESERVE_EPHEMERAL to preserve /mnt.
218     type: string
219   KeyName:
220     default: default
221     description: Name of an existing EC2 KeyPair to enable SSH access to the instances
222     type: string
223     constraints:
224       - custom_constraint: nova.keypair
225   KeystoneCACertificate:
226     default: ''
227     description: Keystone self-signed certificate authority certificate.
228     type: string
229   KeystoneSigningCertificate:
230     default: ''
231     description: Keystone certificate for verifying token validity.
232     type: string
233   KeystoneSigningKey:
234     default: ''
235     description: Keystone key for signing tokens.
236     type: string
237     hidden: true
238   KeystoneSSLCertificate:
239     default: ''
240     description: Keystone certificate for verifying token validity.
241     type: string
242   KeystoneSSLCertificateKey:
243     default: ''
244     description: Keystone key for signing tokens.
245     type: string
246     hidden: true
247   MysqlClusterUniquePart:
248     description: A unique identifier of the MySQL cluster the controller is in.
249     type: string
250     default: 'unset'  # Has to be here because of the ignored empty value bug
251     # Drop the validation: https://bugs.launchpad.net/tripleo/+bug/1405446
252     # constraints:
253     # - length: {min: 4, max: 10}
254   MysqlInnodbBufferPoolSize:
255     description: >
256         Specifies the size of the buffer pool in megabytes. Setting to
257         zero should be interpreted as "no value" and will defer to the
258         lower level default.
259     type: number
260     default: 0
261   MysqlRootPassword:
262     type: string
263     hidden: true
264     default: ''  # Has to be here because of the ignored empty value bug
265   NeutronExternalNetworkBridge:
266     description: Name of bridge used for external network traffic.
267     type: string
268     default: 'br-ex'
269   NeutronBridgeMappings:
270     description: >
271       The OVS logical->physical bridge mappings to use. See the Neutron
272       documentation for details. Defaults to mapping br-ex - the external
273       bridge on hosts - to a physical name 'datacentre' which can be used
274       to create provider networks (and we use this for the default floating
275       network) - if changing this either use different post-install network
276       scripts or be sure to keep 'datacentre' as a mapping network name.
277     type: string
278     default: "datacentre:br-ex"
279   NeutronDnsmasqOptions:
280     default: 'dhcp-option-force=26,1400'
281     description: Dnsmasq options for neutron-dhcp-agent. The default value here forces MTU to be set to 1400 to account for the gre tunnel overhead.
282     type: string
283   NeutronAgentMode:
284     default: 'dvr_snat'
285     description: Agent mode for the neutron-l3-agent on the controller hosts
286     type: string
287   NeutronL3HA:
288     default: 'False'
289     description: Whether to enable l3-agent HA
290     type: string
291   NeutronDhcpAgentsPerNetwork:
292     type: number
293     default: 3
294     description: The number of neutron dhcp agents to schedule per network
295   NeutronDVR:
296     default: 'False'
297     description: Whether to configure Neutron Distributed Virtual Routers
298     type: string
299   NeutronMetadataProxySharedSecret:
300     default: 'unset'
301     description: Shared secret to prevent spoofing
302     type: string
303   NeutronMechanismDrivers:
304     default: 'openvswitch'
305     description: |
306         The mechanism drivers for the Neutron tenant network. To specify multiple
307         values, use a comma separated string, like so: 'openvswitch,l2_population'
308     type: string
309   NeutronAllowL3AgentFailover:
310     default: 'True'
311     description: Allow automatic l3-agent failover
312     type: string
313   NeutronEnableTunnelling:
314     type: string
315     default: "True"
316   NeutronFlatNetworks:
317     type: string
318     default: 'datacentre'
319     description: If set, flat networks to configure in neutron plugins.
320   NeutronL3HA:
321     default: 'False'
322     description: Whether to enable l3-agent HA
323     type: string
324   NeutronNetworkType:
325     default: 'gre'
326     description: The tenant network type for Neutron, either gre or vxlan.
327     type: string
328   NeutronNetworkVLANRanges:
329     default: 'datacentre'
330     description: >
331       The Neutron ML2 and OpenVSwitch vlan mapping range to support. See the
332       Neutron documentation for permitted values. Defaults to permitting any
333       VLAN on the 'datacentre' physical network (See NeutronBridgeMappings).
334     type: comma_delimited_list
335   NeutronPassword:
336     default: unset
337     description: The password for the neutron service and db account, used by neutron agents.
338     type: string
339     hidden: true
340   NeutronPublicInterface:
341     default: nic1
342     description: What interface to bridge onto br-ex for network nodes.
343     type: string
344   NeutronPublicInterfaceTag:
345     default: ''
346     description: >
347       VLAN tag for creating a public VLAN. The tag will be used to
348       create an access port on the exterior bridge for each control plane node,
349       and that port will be given the IP address returned by neutron from the
350       public network. Set CONTROLEXTRA=overcloud-vlan-port.yaml when compiling
351       overcloud.yaml to include the deployment of VLAN ports to the control
352       plane.
353     type: string
354   NeutronPublicInterfaceDefaultRoute:
355     default: ''
356     description: A custom default route for the NeutronPublicInterface.
357     type: string
358   NeutronPublicInterfaceIP:
359     default: ''
360     description: A custom IP address to put onto the NeutronPublicInterface.
361     type: string
362   NeutronPublicInterfaceRawDevice:
363     default: ''
364     description: If set, the public interface is a vlan with this device as the raw device.
365     type: string
366   NeutronTunnelTypes:
367     default: 'gre'
368     description: |
369         The tunnel types for the Neutron tenant network. To specify multiple
370         values, use a comma separated string, like so: 'gre,vxlan'
371     type: string
372   NovaPassword:
373     default: unset
374     description: The password for the nova service and db account, used by nova-api.
375     type: string
376     hidden: true
377   NtpServer:
378     type: string
379     default: ''
380   PcsdPassword:
381     type: string
382     description: The password for the 'pcsd' user.
383   PublicVirtualInterface:
384     default: 'br-ex'
385     description: >
386         Specifies the interface where the public-facing virtual ip will be assigned.
387         This should be int_public when a VLAN is being used.
388     type: string
389   PublicVirtualIP: # DEPRECATED: use per service settings instead
390     type: string
391     default: ''  # Has to be here because of the ignored empty value bug
392   RabbitCookie:
393     type: string
394     default: ''  # Has to be here because of the ignored empty value bug
395     hidden: true
396   RabbitPassword:
397     default: guest
398     description: The password for RabbitMQ
399     type: string
400     hidden: true
401   RabbitUserName:
402     default: guest
403     description: The username for RabbitMQ
404     type: string
405   RabbitClientUseSSL:
406     default: false
407     description: >
408         Rabbit client subscriber parameter to specify
409         an SSL connection to the RabbitMQ host.
410     type: string
411   RabbitClientPort:
412     default: 5672
413     description: Set rabbit subscriber port, change this if using SSL
414     type: number
415   RedisVirtualIP:
416     type: string
417     default: ''  # Has to be here because of the ignored empty value bug
418   SnmpdReadonlyUserName:
419     default: ro_snmp_user
420     description: The user name for SNMPd with readonly rights running on all Overcloud nodes
421     type: string
422   SnmpdReadonlyUserPassword:
423     default: unset
424     description: The user password for SNMPd with readonly rights running on all Overcloud nodes
425     type: string
426     hidden: true
427   SSLCACertificate:
428     default: ''
429     description: If set, the contents of an SSL certificate authority file.
430     type: string
431   SSLCertificate:
432     default: ''
433     description: If set, the contents of an SSL certificate .crt file for encrypting SSL endpoints.
434     type: string
435     hidden: true
436   SSLKey:
437     default: ''
438     description: If set, the contents of an SSL certificate .key file for encrypting SSL endpoints.
439     type: string
440     hidden: true
441   SwiftHashSuffix:
442     default: unset
443     description: A random string to be used as a salt when hashing to determine mappings
444       in the ring.
445     hidden: true
446     type: string
447   SwiftMountCheck:
448     default: 'false'
449     description: Value of mount_check in Swift account/container/object -server.conf
450     type: boolean
451   SwiftMinPartHours:
452     type: number
453     default: 1
454     description: The minimum time (in hours) before a partition in a ring can be moved following a rebalance.
455   SwiftPartPower:
456     default: 10
457     description: Partition Power to use when building Swift rings
458     type: number
459   SwiftPassword:
460     default: unset
461     description: The password for the swift service account, used by the swift proxy
462       services.
463     hidden: true
464     type: string
465   SwiftReplicas:
466     type: number
467     default: 3
468     description: How many replicas to use in the swift rings.
469   VirtualIP: # DEPRECATED: use per service settings instead
470     type: string
471     default: ''  # Has to be here because of the ignored empty value bug
472   HeatApiVirtualIP:
473     type: string
474     default: ''
475   GlanceApiVirtualIP:
476     type: string
477     default: ''
478   MysqlVirtualIP:
479     type: string
480     default: ''
481   KeystonePublicApiVirtualIP:
482     type: string
483     default: ''
484   NeutronApiVirtualIP:
485     type: string
486     default: ''
487   EnablePackageInstall:
488     default: 'false'
489     description: Set to true to enable package installation via Puppet
490     type: boolean
491   ServiceNetMap:
492     default: {}
493     description: Mapping of service_name -> network name. Typically set
494                  via parameter_defaults in the resource registry.
495     type: json
496   UpdateIdentifier:
497     default: ''
498     type: string
499     description: >
500       Setting to a previously unused value during stack-update will trigger
501       package update on all nodes
502   Hostname:
503     type: string
504     default: '' # Defaults to Heat created hostname
505
506 resources:
507
508   Controller:
509     type: OS::Nova::Server
510     properties:
511       image: {get_param: Image}
512       image_update_policy: {get_param: ImageUpdatePolicy}
513       flavor: {get_param: Flavor}
514       key_name: {get_param: KeyName}
515       networks:
516         - network: ctlplane
517       user_data_format: SOFTWARE_CONFIG
518       user_data: {get_resource: NodeUserData}
519       name: {get_param: Hostname}
520
521   NodeUserData:
522     type: OS::TripleO::NodeUserData
523
524   ExternalPort:
525     type: OS::TripleO::Controller::Ports::ExternalPort
526     properties:
527       ControlPlaneIP: {get_attr: [Controller, networks, ctlplane, 0]}
528
529   InternalApiPort:
530     type: OS::TripleO::Controller::Ports::InternalApiPort
531     properties:
532       ControlPlaneIP: {get_attr: [Controller, networks, ctlplane, 0]}
533
534   StoragePort:
535     type: OS::TripleO::Controller::Ports::StoragePort
536     properties:
537       ControlPlaneIP: {get_attr: [Controller, networks, ctlplane, 0]}
538
539   StorageMgmtPort:
540     type: OS::TripleO::Controller::Ports::StorageMgmtPort
541     properties:
542       ControlPlaneIP: {get_attr: [Controller, networks, ctlplane, 0]}
543
544   TenantPort:
545     type: OS::TripleO::Controller::Ports::TenantPort
546     properties:
547       ControlPlaneIP: {get_attr: [Controller, networks, ctlplane, 0]}
548
549   NetIpMap:
550     type: OS::TripleO::Network::Ports::NetIpMap
551     properties:
552       ExternalIp: {get_attr: [ExternalPort, ip_address]}
553       InternalApiIp: {get_attr: [InternalApiPort, ip_address]}
554       StorageIp: {get_attr: [StoragePort, ip_address]}
555       StorageMgmtIp: {get_attr: [StorageMgmtPort, ip_address]}
556       TenantIp: {get_attr: [TenantPort, ip_address]}
557
558   NetIpSubnetMap:
559     type: OS::TripleO::Network::Ports::NetIpMap
560     properties:
561       ExternalIp: {get_attr: [ExternalPort, ip_subnet]}
562       InternalApiIp: {get_attr: [InternalApiPort, ip_subnet]}
563       StorageIp: {get_attr: [StoragePort, ip_subnet]}
564       StorageMgmtIp: {get_attr: [StorageMgmtPort, ip_subnet]}
565       TenantIp: {get_attr: [TenantPort, ip_subnet]}
566
567   NetworkConfig:
568     type: OS::TripleO::Controller::Net::SoftwareConfig
569     properties:
570       ExternalIpSubnet: {get_attr: [ExternalPort, ip_subnet]}
571       InternalApiIpSubnet: {get_attr: [InternalApiPort, ip_subnet]}
572       StorageIpSubnet: {get_attr: [StoragePort, ip_subnet]}
573       StorageMgmtIpSubnet: {get_attr: [StorageMgmtPort, ip_subnet]}
574       TenantIpSubnet: {get_attr: [TenantPort, ip_subnet]}
575
576   NetworkDeployment:
577     type: OS::TripleO::SoftwareDeployment
578     properties:
579       config: {get_resource: NetworkConfig}
580       server: {get_resource: Controller}
581       input_values:
582         bridge_name: br-ex
583         interface_name: {get_param: NeutronPublicInterface}
584
585   ControllerDeployment:
586     type: OS::TripleO::SoftwareDeployment
587     depends_on: NetworkDeployment
588     properties:
589       config: {get_resource: ControllerConfig}
590       server: {get_resource: Controller}
591       input_values:
592         bootstack_nodeid: {get_attr: [Controller, name]}
593         neutron_enable_tunneling: {get_param: NeutronEnableTunnelling}
594         heat.watch_server_url:
595           list_join:
596             - ''
597             - - 'http://'
598               - {get_param: HeatApiVirtualIP}
599               - ':8003'
600         heat.metadata_server_url:
601           list_join:
602             - ''
603             - - 'http://'
604               - {get_param: HeatApiVirtualIP}
605               - ':8000'
606         heat.waitcondition_server_url:
607           list_join:
608             - ''
609             - - 'http://'
610               - {get_param: HeatApiVirtualIP}
611               - ':8000/v1/waitcondition'
612         heat_auth_encryption_key: {get_param: HeatAuthEncryptionKey}
613         horizon_secret: {get_param: HorizonSecret}
614         admin_password: {get_param: AdminPassword}
615         admin_token: {get_param: AdminToken}
616         neutron_public_interface_ip: {get_param: NeutronPublicInterfaceIP}
617         debug: {get_param: Debug}
618         cinder_enable_rbd_backend: {get_param: CinderEnableRbdBackend}
619         cinder_lvm_loop_device_size: {get_param: CinderLVMLoopDeviceSize}
620         cinder_password: {get_param: CinderPassword}
621         cinder_enable_iscsi_backend: {get_param: CinderEnableIscsiBackend}
622         cinder_iscsi_helper: {get_param: CinderISCSIHelper}
623         cinder_backend_config: {get_param: CinderBackendConfig}
624         cinder_dsn:
625           list_join:
626             - ''
627             - - 'mysql://cinder:'
628               - {get_param: CinderPassword}
629               - '@'
630               - {get_param: MysqlVirtualIP}
631               - '/cinder'
632         glance_port: {get_param: GlancePort}
633         glance_password: {get_param: GlancePassword}
634         glance_backend: {get_param: GlanceBackend}
635         glance_notifier_strategy: {get_param: GlanceNotifierStrategy}
636         glance_log_file: {get_param: GlanceLogFile}
637         glance_dsn:
638           list_join:
639             - ''
640             - - 'mysql://glance:'
641               - {get_param: GlancePassword}
642               - '@'
643               - {get_param: MysqlVirtualIP}
644               - '/glance'
645         heat_password: {get_param: HeatPassword}
646         heat_stack_domain_admin_password: {get_param: HeatStackDomainAdminPassword}
647         heat_dsn:
648           list_join:
649             - ''
650             - - 'mysql://heat:'
651               - {get_param: HeatPassword}
652               - '@'
653               - {get_param: MysqlVirtualIP}
654               - '/heat'
655         keystone_auth_address: {list_join: ['', ['http://', {get_param: KeystonePublicApiVirtualIP} , ':5000/v2.0']]}
656         keystone_ca_certificate: {get_param: KeystoneCACertificate}
657         keystone_signing_key: {get_param: KeystoneSigningKey}
658         keystone_signing_certificate: {get_param: KeystoneSigningCertificate}
659         keystone_ssl_certificate: {get_param: KeystoneSSLCertificate}
660         keystone_ssl_certificate_key: {get_param: KeystoneSSLCertificateKey}
661         keystone_dsn:
662           list_join:
663             - ''
664             - - 'mysql://keystone:'
665               - {get_param: AdminToken}
666               - '@'
667               - {get_param: MysqlVirtualIP}
668               - '/keystone'
669         keystone_identity_uri:
670           list_join:
671             - ''
672             - - 'http://'
673               - {get_param: KeystonePublicApiVirtualIP}
674               - ':35357/'
675         keystone_auth_uri:
676           list_join:
677             - ''
678             - - 'http://'
679               - {get_param: KeystonePublicApiVirtualIP}
680               - ':5000/v2.0/'
681         enable_fencing: {get_param: EnableFencing}
682         enable_galera: {get_param: EnableGalera}
683         enable_ceph_storage: {get_param: EnableCephStorage}
684         enable_swift_storage: {get_param: EnableSwiftStorage}
685         mysql_innodb_buffer_pool_size: {get_param: MysqlInnodbBufferPoolSize}
686         mysql_root_password: {get_param: MysqlRootPassword}
687         mysql_cluster_name:
688           str_replace:
689             template: tripleo-CLUSTER
690             params:
691               CLUSTER: {get_param: MysqlClusterUniquePart}
692         neutron_flat_networks: {get_param: NeutronFlatNetworks}
693         neutron_metadata_proxy_shared_secret: {get_param: NeutronMetadataProxySharedSecret}
694         neutron_agent_mode: {get_param: NeutronAgentMode}
695         neutron_router_distributed: {get_param: NeutronDVR}
696         neutron_mechanism_drivers: {get_param: NeutronMechanismDrivers}
697         neutron_allow_l3agent_failover: {get_param: NeutronAllowL3AgentFailover}
698         neutron_l3_ha: {get_param: NeutronL3HA}
699         neutron_dhcp_agents_per_network: {get_param: NeutronDhcpAgentsPerNetwork}
700         neutron_network_vlan_ranges:
701           str_replace:
702             template: "['RANGES']"
703             params:
704               RANGES:
705                 list_join:
706                 - "','"
707                 - {get_param: NeutronNetworkVLANRanges}
708         neutron_bridge_mappings: {get_param: NeutronBridgeMappings}
709         neutron_external_network_bridge: {get_param: NeutronExternalNetworkBridge}
710         neutron_public_interface: {get_param: NeutronPublicInterface}
711         neutron_public_interface_raw_device: {get_param: NeutronPublicInterfaceRawDevice}
712         neutron_public_interface_default_route: {get_param: NeutronPublicInterfaceDefaultRoute}
713         neutron_public_interface_tag: {get_param: NeutronPublicInterfaceTag}
714         neutron_tenant_network_type: {get_param: NeutronNetworkType}
715         neutron_tunnel_types: {get_param: NeutronTunnelTypes}
716         neutron_password: {get_param: NeutronPassword}
717         neutron_dnsmasq_options: {get_param: NeutronDnsmasqOptions}
718         neutron_dsn:
719           list_join:
720             - ''
721             - - 'mysql://neutron:'
722               - {get_param: NeutronPassword}
723               - '@'
724               - {get_param: MysqlVirtualIP}
725               - '/ovs_neutron?charset=utf8'
726         neutron_url:
727           list_join:
728             - ''
729             - - 'http://'
730               - {get_param: NeutronApiVirtualIP}
731               - ':9696'
732         neutron_admin_auth_url:
733           list_join:
734             - ''
735             - - 'http://'
736               - {get_param: KeystonePublicApiVirtualIP}
737               - ':35357/v2.0'
738         ceilometer_backend: {get_param: CeilometerBackend}
739         ceilometer_metering_secret: {get_param: CeilometerMeteringSecret}
740         ceilometer_password: {get_param: CeilometerPassword}
741         ceilometer_coordination_url:
742           list_join:
743             - ''
744             - - 'redis://'
745               - {get_param: RedisVirtualIP}
746               - ':6379'
747         ceilometer_dsn:
748           list_join:
749             - ''
750             - - 'mysql://ceilometer:unset@'
751               - {get_param: MysqlVirtualIP}
752               - '/ceilometer'
753         snmpd_readonly_user_name: {get_param: SnmpdReadonlyUserName}
754         snmpd_readonly_user_password: {get_param: SnmpdReadonlyUserPassword}
755         nova_password: {get_param: NovaPassword}
756         nova_dsn:
757           list_join:
758             - ''
759             - - 'mysql://nova:'
760               - {get_param: NovaPassword}
761               - '@'
762               - {get_param: MysqlVirtualIP}
763               - '/nova'
764         fencing_config: {get_param: FencingConfig}
765         pcsd_password: {get_param: PcsdPassword}
766         rabbit_username: {get_param: RabbitUserName}
767         rabbit_password: {get_param: RabbitPassword}
768         rabbit_cookie: {get_param: RabbitCookie}
769         rabbit_client_use_ssl: {get_param: RabbitClientUseSSL}
770         rabbit_client_port: {get_param: RabbitClientPort}
771         ntp_servers:
772           str_replace:
773             template: '["server"]'
774             params:
775               server: {get_param: NtpServer}
776         control_virtual_interface: {get_param: ControlVirtualInterface}
777         public_virtual_interface: {get_param: PublicVirtualInterface}
778         swift_hash_suffix: {get_param: SwiftHashSuffix}
779         swift_password: {get_param: SwiftPassword}
780         swift_part_power: {get_param: SwiftPartPower}
781         swift_replicas: {get_param: SwiftReplicas}
782         swift_min_part_hours: {get_param: SwiftMinPartHours}
783         swift_mount_check: {get_param: SwiftMountCheck}
784         enable_package_install: {get_param: EnablePackageInstall}
785         swift_proxy_network: {get_attr: [NetIpMap, net_ip_map, {get_param: [ServiceNetMap, SwiftProxyNetwork]}]}
786         swift_management_network: {get_attr: [NetIpMap, net_ip_map, {get_param: [ServiceNetMap, SwiftMgmtNetwork]}]}
787         cinder_iscsi_network: {get_attr: [NetIpMap, net_ip_map, {get_param: [ServiceNetMap, CinderIscsiNetwork]}]}
788         cinder_api_network: {get_attr: [NetIpMap, net_ip_map, {get_param: [ServiceNetMap, CinderApiNetwork]}]}
789         glance_api_network: {get_attr: [NetIpMap, net_ip_map, {get_param: [ServiceNetMap, GlanceApiNetwork]}]}
790         glance_registry_network: {get_attr: [NetIpMap, net_ip_map, {get_param: [ServiceNetMap, GlanceRegistryNetwork]}]}
791         glance_api_servers:
792           list_join:
793             - ''
794             - - {get_param: GlanceProtocol}
795               - '://'
796               - {get_param: GlanceApiVirtualIP}
797               - ':'
798               - {get_param: GlancePort}
799         heat_api_network: {get_attr: [NetIpMap, net_ip_map, {get_param: [ServiceNetMap, HeatApiNetwork]}]}
800         keystone_public_api_network: {get_attr: [NetIpMap, net_ip_map, {get_param: [ServiceNetMap, KeystonePublicApiNetwork]}]}
801         keystone_admin_api_network: {get_attr: [NetIpMap, net_ip_map, {get_param: [ServiceNetMap, KeystoneAdminApiNetwork]}]}
802         mongo_db_network: {get_attr: [NetIpMap, net_ip_map, {get_param: [ServiceNetMap, MongoDbNetwork]}]}
803         neutron_api_network: {get_attr: [NetIpMap, net_ip_map, {get_param: [ServiceNetMap, NeutronApiNetwork]}]}
804         neutron_local_ip: {get_attr: [NetIpMap, net_ip_map, {get_param: [ServiceNetMap, NeutronTenantNetwork]}]}
805         ceilometer_api_network: {get_attr: [NetIpMap, net_ip_map, {get_param: [ServiceNetMap, CeilometerApiNetwork]}]}
806         nova_api_network: {get_attr: [NetIpMap, net_ip_map, {get_param: [ServiceNetMap, NovaApiNetwork]}]}
807         nova_metadata_network: {get_attr: [NetIpMap, net_ip_map, {get_param: [ServiceNetMap, NovaMetadataNetwork]}]}
808         horizon_network: {get_attr: [NetIpMap, net_ip_map, {get_param: [ServiceNetMap, HorizonNetwork]}]}
809         rabbitmq_network: {get_attr: [NetIpMap, net_ip_map, {get_param: [ServiceNetMap, RabbitMqNetwork]}]}
810         redis_network: {get_attr: [NetIpMap, net_ip_map, {get_param: [ServiceNetMap, RedisNetwork]}]}
811         redis_vip: {get_param: RedisVirtualIP}
812         memcached_network: {get_attr: [NetIpMap, net_ip_map, {get_param: [ServiceNetMap, MemcachedNetwork]}]}
813         mysql_network: {get_attr: [NetIpMap, net_ip_map, {get_param: [ServiceNetMap, MysqlNetwork]}]}
814         ceph_cluster_network: {get_attr: [NetIpSubnetMap, net_ip_map, {get_param: [ServiceNetMap, CephClusterNetwork]}]}
815         ceph_public_network: {get_attr: [NetIpSubnetMap, net_ip_map, {get_param: [ServiceNetMap, CephPublicNetwork]}]}
816         ceph_public_ip: {get_attr: [NetIpMap, net_ip_map, {get_param: [ServiceNetMap, CephPublicNetwork]}]}
817
818   # Map heat metadata into hiera datafiles
819   ControllerConfig:
820     type: OS::Heat::StructuredConfig
821     properties:
822       group: os-apply-config
823       config:
824         hiera:
825           hierarchy:
826             - heat_config_%{::deploy_config_name}
827             - controller
828             - object
829             - swift_devices_and_proxy # provided by SwiftDevicesAndProxyConfig
830             - ceph_cluster # provided by CephClusterConfig
831             - ceph
832             - bootstrap_node # provided by BootstrapNodeConfig
833             - all_nodes # provided by allNodesConfig
834             - vip_data # provided by vip-config
835             - '"%{::osfamily}"'
836             - common
837             - cinder_netapp_data # Optionally provided by ControllerExtraConfigPre
838           datafiles:
839             common:
840               raw_data: {get_file: hieradata/common.yaml}
841             ceph:
842               raw_data: {get_file: hieradata/ceph.yaml}
843               mapped_data:
844                 ceph::profile::params::cluster_network: {get_input: ceph_cluster_network}
845                 ceph::profile::params::public_network: {get_input: ceph_public_network}
846                 ceph::mon::public_addr: {get_input: ceph_public_ip}
847             object:
848               raw_data: {get_file: hieradata/object.yaml}
849             controller:
850               raw_data: {get_file: hieradata/controller.yaml}
851               mapped_data: # data supplied directly to this deployment configuration, etc
852                 bootstack_nodeid: {get_input: bootstack_nodeid}
853
854                 # Pacemaker
855                 enable_fencing: {get_input: enable_fencing}
856                 hacluster_pwd: {get_input: pcsd_password}
857                 tripleo::fencing::config: {get_input: fencing_config}
858
859                 # Swift
860                 swift::proxy::proxy_local_net_ip: {get_input: swift_proxy_network}
861                 swift::proxy::authtoken::auth_uri: {get_input: keystone_auth_uri}
862                 swift::proxy::authtoken::identity_uri: {get_input: keystone_identity_uri}
863                 swift::storage::all::storage_local_net_ip: {get_input: swift_management_network}
864                 swift::swift_hash_suffix: {get_input: swift_hash_suffix}
865                 swift::proxy::authtoken::admin_password: {get_input: swift_password}
866                 tripleo::ringbuilder::part_power: {get_input: swift_part_power}
867                 tripleo::ringbuilder::replicas: {get_input: swift_replicas}
868                 tripleo::ringbuilder::min_part_hours: {get_input: swift_min_part_hours}
869                 swift_mount_check: {get_input: swift_mount_check}
870
871                 # NOTE(dprince): build_ring support is currently not wired in.
872                 # See: https://review.openstack.org/#/c/109225/
873                 tripleo::ringbuilder::build_ring: True
874
875                 # Cinder
876                 cinder_enable_rbd_backend: {get_input: cinder_enable_rbd_backend}
877                 cinder_lvm_loop_device_size: {get_input: cinder_lvm_loop_device_size}
878                 cinder_iscsi_helper: {get_input: cinder_iscsi_helper}
879                 cinder_iscsi_ip_address: {get_input: cinder_iscsi_network}
880                 cinder::database_connection: {get_input: cinder_dsn}
881                 cinder::api::keystone_password: {get_input: cinder_password}
882                 cinder::api::auth_uri: {get_input: keystone_auth_uri}
883                 cinder::api::identity_uri: {get_input: keystone_identity_uri}
884                 cinder::api::bind_host: {get_input: cinder_api_network}
885                 cinder::rabbit_userid: {get_input: rabbit_username}
886                 cinder::rabbit_password: {get_input: rabbit_password}
887                 cinder::rabbit_use_ssl: {get_input: rabbit_client_use_ssl}
888                 cinder::rabbit_port: {get_input: rabbit_client_port}
889                 cinder::debug: {get_input: debug}
890                 cinder_enable_iscsi_backend: {get_input: cinder_enable_iscsi_backend}
891                 cinder::glance::glance_api_servers: {get_input: glance_api_servers}
892                 cinder_backend_config: {get_input: CinderBackendConfig}
893
894                 # Glance
895                 glance::api::bind_port: {get_input: glance_port}
896                 glance::api::bind_host: {get_input: glance_api_network}
897                 glance::api::auth_uri: {get_input: keystone_auth_uri}
898                 glance::api::identity_uri: {get_input: keystone_identity_uri}
899                 glance::api::registry_host: {get_input: glance_registry_network}
900                 glance::api::keystone_password: {get_input: glance_password}
901                 glance::api::debug: {get_input: debug}
902                 glance_notifier_strategy: {get_input: glance_notifier_strategy}
903                 glance_log_file: {get_input: glance_log_file}
904                 glance_log_file: {get_input: glance_log_file}
905                 glance::api::database_connection: {get_input: glance_dsn}
906                 glance::registry::keystone_password: {get_input: glance_password}
907                 glance::registry::database_connection: {get_input: glance_dsn}
908                 glance::registry::bind_host: {get_attr: [NetIpMap, net_ip_map, {get_param: [ServiceNetMap, GlanceRegistryNetwork]}]}
909                 glance::registry::auth_uri: {get_input: keystone_auth_uri}
910                 glance::registry::identity_uri: {get_input: keystone_identity_uri}
911                 glance::registry::debug: {get_input: debug}
912                 glance::backend::swift::swift_store_auth_address: {get_input: keystone_auth_address}
913                 glance::backend::swift::swift_store_user: service:glance
914                 glance::backend::swift::swift_store_key: {get_input: glance_password}
915                 glance_backend: {get_input: glance_backend}
916
917                 # Heat
918                 heat_stack_domain_admin_password: {get_input: heat_stack_domain_admin_password}
919                 heat::engine::heat_watch_server_url: {get_input: heat.watch_server_url}
920                 heat::engine::heat_metadata_server_url: {get_input: heat.metadata_server_url}
921                 heat::engine::heat_waitcondition_server_url: {get_input: heat.waitcondition_server_url}
922                 heat::engine::auth_encryption_key: {get_input: heat_auth_encryption_key}
923                 heat::rabbit_userid: {get_input: rabbit_username}
924                 heat::rabbit_password: {get_input: rabbit_password}
925                 heat::rabbit_use_ssl: {get_input: rabbit_client_use_ssl}
926                 heat::rabbit_port: {get_input: rabbit_client_port}
927                 heat::auth_uri: {get_input: keystone_auth_uri}
928                 heat::identity_uri: {get_input: keystone_identity_uri}
929                 heat::keystone_password: {get_input: heat_password}
930                 heat::api::bind_host: {get_input: heat_api_network}
931                 heat::api_cloudwatch::bind_host: {get_input: heat_api_network}
932                 heat::api_cfn::bind_host: {get_input: heat_api_network}
933                 heat::database_connection: {get_input: heat_dsn}
934                 heat::instance_user: heat-admin
935                 heat::debug: {get_input: debug}
936
937                 # Keystone
938                 keystone::admin_token: {get_input: admin_token}
939                 keystone_ca_certificate: {get_input: keystone_ca_certificate}
940                 keystone_signing_key: {get_input: keystone_signing_key}
941                 keystone_signing_certificate: {get_input: keystone_signing_certificate}
942                 keystone_ssl_certificate: {get_input: keystone_ssl_certificate}
943                 keystone_ssl_certificate_key: {get_input: keystone_ssl_certificate_key}
944                 keystone::database_connection: {get_input: keystone_dsn}
945                 keystone::public_bind_host: {get_input: keystone_public_api_network}
946                 keystone::admin_bind_host: {get_input: keystone_admin_api_network}
947                 keystone::debug: {get_input: debug}
948                 # MongoDB
949                 mongodb::server::bind_ip: {get_input: mongo_db_network}
950                 # MySQL
951                 admin_password: {get_input: admin_password}
952                 enable_galera: {get_input: enable_galera}
953                 enable_ceph_storage: {get_input: enable_ceph_storage}
954                 enable_swift_storage: {get_input: enable_swift_storage}
955                 mysql_innodb_buffer_pool_size: {get_input: mysql_innodb_buffer_pool_size}
956                 mysql::server::root_password: {get_input: mysql_root_password}
957                 mysql_cluster_name: {get_input: mysql_cluster_name}
958                 mysql_bind_host: {get_input: mysql_network}
959
960                 # Neutron
961                 neutron::bind_host: {get_input: neutron_api_network}
962                 neutron::rabbit_password: {get_input: rabbit_password}
963                 neutron::rabbit_user: {get_input: rabbit_user}
964                 neutron::rabbit_use_ssl: {get_input: rabbit_client_use_ssl}
965                 neutron::rabbit_port: {get_input: rabbit_client_port}
966                 neutron::debug: {get_input: debug}
967                 neutron::server::auth_uri: {get_input: keystone_auth_uri}
968                 neutron::server::identity_uri: {get_input: keystone_identity_uri}
969                 neutron::server::database_connection: {get_input: neutron_dsn}
970                 neutron::agents::l3::external_network_bridge: {get_input: neutron_external_network_bridge}
971                 neutron::agents::ml2::ovs::enable_tunneling: {get_input: neutron_enable_tunneling}
972                 neutron::agents::ml2::ovs::local_ip: {get_input: neutron_local_ip}
973                 neutron_flat_networks: {get_input: neutron_flat_networks}
974                 neutron::agents::metadata::shared_secret: {get_input: neutron_metadata_proxy_shared_secret}
975                 neutron::agents::metadata::metadata_ip: {get_input: neutron_api_network}
976                 neutron_agent_mode: {get_input: neutron_agent_mode}
977                 neutron_router_distributed: {get_input: neutron_router_distributed}
978                 neutron_mechanism_drivers: {get_input: neutron_mechanism_drivers}
979                 neutron::server::allow_automatic_l3agent_failover: {get_input: neutron_allow_l3agent_failover}
980                 neutron::server::l3_ha: {get_input: neutron_l3_ha}
981                 neutron::dhcp_agents_per_network: {get_input: neutron_dhcp_agents_per_network}
982                 neutron::plugins::ml2::network_vlan_ranges: {get_input: neutron_network_vlan_ranges}
983                 neutron_bridge_mappings: {get_input: neutron_bridge_mappings}
984                 neutron_public_interface: {get_input: neutron_public_interface}
985                 neutron_public_interface_raw_device: {get_input: neutron_public_interface_raw_device}
986                 neutron_public_interface_default_route: {get_input: neutron_public_interface_default_route}
987                 neutron_public_interface_tag: {get_input: neutron_public_interface_tag}
988                 neutron_tenant_network_type: {get_input: neutron_tenant_network_type}
989                 neutron_tunnel_types: {get_input: neutron_tunnel_types}
990                 neutron::server::auth_password: {get_input: neutron_password}
991                 neutron::agents::metadata::auth_password: {get_input: neutron_password}
992                 neutron_dnsmasq_options: {get_input: neutron_dnsmasq_options}
993                 neutron_dsn: {get_input: neutron_dsn}
994                 neutron::agents::metadata::auth_url: {get_input: keystone_identity_uri}
995
996                 # Ceilometer
997                 ceilometer_backend: {get_input: ceilometer_backend}
998                 ceilometer_mysql_conn_string: {get_input: ceilometer_dsn}
999                 ceilometer::metering_secret: {get_input: ceilometer_metering_secret}
1000                 ceilometer::rabbit_userid: {get_input: rabbit_username}
1001                 ceilometer::rabbit_password: {get_input: rabbit_password}
1002                 ceilometer::rabbit_use_ssl: {get_input: rabbit_client_use_ssl}
1003                 ceilometer::rabbit_port: {get_input: rabbit_client_port}
1004                 ceilometer::debug: {get_input: debug}
1005                 ceilometer::api::host: {get_input: ceilometer_api_network}
1006                 ceilometer::api::keystone_password: {get_input: ceilometer_password}
1007                 ceilometer::api::keystone_auth_uri: {get_input: keystone_auth_uri}
1008                 ceilometer::api::keystone_identity_uri: {get_input: keystone_identity_uri}
1009                 ceilometer::agent::auth::auth_password: {get_input: ceilometer_password}
1010                 ceilometer::agent::auth::auth_url: {get_input: keystone_auth_address}
1011                 ceilometer::agent::central::coordination_url: {get_input: ceilometer_coordination_url}
1012                 snmpd_readonly_user_name: {get_input: snmpd_readonly_user_name}
1013                 snmpd_readonly_user_password: {get_input: snmpd_readonly_user_password}
1014
1015                 # Nova
1016                 nova::rabbit_userid: {get_input: rabbit_username}
1017                 nova::rabbit_password: {get_input: rabbit_password}
1018                 nova::rabbit_use_ssl: {get_input: rabbit_client_use_ssl}
1019                 nova::rabbit_port: {get_input: rabbit_client_port}
1020                 nova::debug: {get_input: debug}
1021                 nova::api::auth_uri: {get_input: keystone_auth_uri}
1022                 nova::api::identity_uri: {get_input: keystone_identity_uri}
1023                 nova::api::api_bind_address: {get_input: nova_api_network}
1024                 nova::api::metadata_listen: {get_input: nova_metadata_network}
1025                 nova::api::admin_password: {get_input: nova_password}
1026                 nova::database_connection: {get_input: nova_dsn}
1027                 nova::glance_api_servers: {get_input: glance_api_servers}
1028                 nova::api::neutron_metadata_proxy_shared_secret: {get_input: neutron_metadata_proxy_shared_secret}
1029                 nova::network::neutron::neutron_admin_password: {get_input: neutron_password}
1030                 nova::network::neutron::neutron_url: {get_input: neutron_url}
1031                 nova::network::neutron::neutron_admin_auth_url: {get_input: neutron_admin_auth_url}
1032                 nova::vncproxy::host: {get_input: nova_api_network}
1033
1034                 # Horizon
1035                 apache::ip: {get_input: horizon_network}
1036                 horizon::django_debug: {get_input: debug}
1037                 horizon::secret_key: {get_input: horizon_secret}
1038                 horizon::bind_address: {get_input: horizon_network}
1039                 horizon::keystone_url: {get_input: keystone_auth_uri}
1040
1041                 # Rabbit
1042                 rabbitmq::node_ip_address: {get_input: rabbitmq_network}
1043                 rabbitmq::erlang_cookie: {get_input: rabbit_cookie}
1044                 # Redis
1045                 redis::bind: {get_input: redis_network}
1046                 redis_vip: {get_input: redis_vip}
1047                 # Misc
1048                 memcached::listen_ip: {get_input: memcached_network}
1049                 neutron_public_interface_ip: {get_input: neutron_public_interface_ip}
1050                 ntp::servers: {get_input: ntp_servers}
1051                 control_virtual_interface: {get_input: control_virtual_interface}
1052                 public_virtual_interface: {get_input: public_virtual_interface}
1053                 tripleo::loadbalancer::control_virtual_interface: {get_input: control_virtual_interface}
1054                 tripleo::loadbalancer::public_virtual_interface: {get_input: public_virtual_interface}
1055                 enable_package_install: {get_input: enable_package_install}
1056
1057   # Hook for site-specific additional pre-deployment config, e.g extra hieradata
1058   ControllerExtraConfigPre:
1059     depends_on: ControllerDeployment
1060     type: OS::TripleO::ControllerExtraConfigPre
1061     properties:
1062         server: {get_resource: Controller}
1063
1064   UpdateConfig:
1065     type: OS::TripleO::Tasks::PackageUpdate
1066
1067   UpdateDeployment:
1068     type: OS::Heat::SoftwareDeployment
1069     properties:
1070       config: {get_resource: UpdateConfig}
1071       server: {get_resource: Controller}
1072       input_values:
1073         update_identifier:
1074           get_param: UpdateIdentifier
1075
1076 outputs:
1077   ip_address:
1078     description: IP address of the server in the ctlplane network
1079     value: {get_attr: [Controller, networks, ctlplane, 0]}
1080   external_ip_address:
1081     description: IP address of the server in the external network
1082     value: {get_attr: [ExternalPort, ip_address]}
1083   internal_api_ip_address:
1084     description: IP address of the server in the internal_api network
1085     value: {get_attr: [InternalApiPort, ip_address]}
1086   storage_ip_address:
1087     description: IP address of the server in the storage network
1088     value: {get_attr: [StoragePort, ip_address]}
1089   storage_mgmt_ip_address:
1090     description: IP address of the server in the storage_mgmt network
1091     value: {get_attr: [StorageMgmtPort, ip_address]}
1092   tenant_ip_address:
1093     description: IP address of the server in the tenant network
1094     value: {get_attr: [TenantPort, ip_address]}
1095   hostname:
1096     description: Hostname of the server
1097     value: {get_attr: [Controller, name]}
1098   corosync_node:
1099     description: >
1100       Node object in the format {ip: ..., name: ...} format that the corosync
1101       element expects
1102     value:
1103       ip: {get_attr: [Controller, networks, ctlplane, 0]}
1104       name: {get_attr: [Controller, name]}
1105   hosts_entry:
1106     description: >
1107       Server's IP address and hostname in the /etc/hosts format
1108     value:
1109       str_replace:
1110         template: IP HOST.localdomain HOST CLOUDNAME
1111         params:
1112           IP: {get_attr: [NetIpMap, net_ip_map, {get_param: [ServiceNetMap, ControllerHostnameResolveNetwork]}]}
1113           HOST: {get_attr: [Controller, name]}
1114           CLOUDNAME: {get_param: CloudName}
1115   nova_server_resource:
1116     description: Heat resource handle for the Nova compute server
1117     value:
1118       {get_resource: Controller}
1119   swift_device:
1120     description: Swift device formatted for swift-ring-builder
1121     value:
1122       str_replace:
1123         template: 'r1z1-IP:%PORT%/d1'
1124         params:
1125           IP: {get_attr: [NetIpMap, net_ip_map, {get_param: [ServiceNetMap, SwiftMgmtNetwork]}]}
1126   swift_proxy_memcache:
1127     description: Swift proxy-memcache value
1128     value:
1129       str_replace:
1130         template: "IP:11211"
1131         params:
1132           IP: {get_attr: [NetIpMap, net_ip_map, {get_param: [ServiceNetMap, MemcachedNetwork]}]}
1133   config_identifier:
1134     description: identifier which changes if the controller configuration may need re-applying
1135     value:
1136       list_join:
1137       - ','
1138       - - {get_attr: [ControllerDeployment, deploy_stdout]}
1139         - {get_attr: [ControllerExtraConfigPre, deploy_stdout]}