Change ManageEventPipeline to true
[apex-tripleo-heat-templates.git] / common / deploy-steps.j2
1 # certain initialization steps (run in a container) will occur
2 # on the role marked as primary controller or the first role listed
3 {%- set primary_role = [roles[0]] -%}
4 {%- for role in roles -%}
5   {%- if 'primary' in role.tags and 'controller' in role.tags -%}
6     {%- set _ = primary_role.pop() -%}
7     {%- set _ = primary_role.append(role) -%}
8   {%- endif -%}
9 {%- endfor -%}
10 {%- set primary_role_name = primary_role[0].name -%}
11 # primary role is: {{primary_role_name}}
12 {% set deploy_steps_max = 6 -%}
13 {% set update_steps_max = 6 -%}
14 {% set upgrade_steps_max = 6 -%}
15
16 heat_template_version: pike
17
18 description: >
19   Post-deploy configuration steps via puppet for all roles,
20   as defined in ../roles_data.yaml
21
22 parameters:
23   servers:
24     type: json
25     description: Mapping of Role name e.g Controller to a list of servers
26   stack_name:
27     type: string
28     description: Name of the topmost stack
29   role_data:
30     type: json
31     description: Mapping of Role name e.g Controller to the per-role data
32   DeployIdentifier:
33     default: ''
34     type: string
35     description: >
36       Setting this to a unique value will re-run any deployment tasks which
37       perform configuration on a Heat stack-update.
38   EndpointMap:
39     default: {}
40     description: Mapping of service endpoint -> protocol. Typically set
41                  via parameter_defaults in the resource registry.
42     type: json
43   DockerPuppetDebug:
44     type: string
45     default: ''
46     description: Set to True to enable debug logging with docker-puppet.py
47   ctlplane_service_ips:
48     type: json
49
50 conditions:
51 {% for step in range(1, deploy_steps_max) %}
52   WorkflowTasks_Step{{step}}_Enabled:
53     or:
54     {%- for role in roles %}
55       - not:
56           equals:
57             - get_param: [role_data, {{role.name}}, service_workflow_tasks, step{{step}}]
58             - ''
59       - False
60     {%- endfor %}
61 {% endfor %}
62
63 resources:
64
65   RoleConfig:
66     type: OS::Heat::SoftwareConfig
67     properties:
68       group: ansible
69       options:
70         modulepath: /usr/share/ansible-modules
71       inputs:
72         - name: step
73         - name: role_name
74         - name: update_identifier
75         - name: bootstrap_server_id
76         - name: docker_puppet_debug
77       config:
78         str_replace:
79           template: |
80             - hosts: localhost
81               connection: local
82               tasks:
83               _TASKS
84           params:
85             _TASKS: {get_file: deploy-steps-tasks.yaml}
86
87 {%- for step in range(1, deploy_steps_max) %}
88 # BEGIN service_workflow_tasks handling
89   WorkflowTasks_Step{{step}}:
90     type: OS::Mistral::Workflow
91     condition: WorkflowTasks_Step{{step}}_Enabled
92     depends_on:
93     {%- if step == 1 %}
94     {%- for dep in roles %}
95       - {{dep.name}}PreConfig
96       - {{dep.name}}ArtifactsDeploy
97     {%- endfor %}
98     {%- else %}
99     {%- for dep in roles %}
100       - {{dep.name}}Deployment_Step{{step -1}}
101     {%- endfor %}
102     {%- endif %}
103     properties:
104       name: {list_join: [".", ["tripleo", {get_param: stack_name}, "workflowtasks", "step{{step}}"]]}
105       type: direct
106       tasks:
107         yaql:
108           expression: $.data.where($ != '').select($.get('step{{step}}')).where($ != null).flatten()
109           data:
110           {%- for role in roles %}
111             - get_param: [role_data, {{role.name}}, service_workflow_tasks]
112           {%- endfor %}
113
114   WorkflowTasks_Step{{step}}_Execution:
115     type: OS::Mistral::ExternalResource
116     condition: WorkflowTasks_Step{{step}}_Enabled
117     depends_on: WorkflowTasks_Step{{step}}
118     properties:
119       actions:
120         CREATE:
121           workflow: { get_resource: WorkflowTasks_Step{{step}} }
122           params:
123             env:
124               service_ips: { get_param: ctlplane_service_ips }
125               role_merged_configs:
126                 {%- for r in roles %}
127                 {{r.name}}: {get_param: [role_data, {{r.name}}, merged_config_settings]}
128                 {%- endfor %}
129             evaluate_env: false
130         UPDATE:
131           workflow: { get_resource: WorkflowTasks_Step{{step}} }
132           params:
133             env:
134               service_ips: { get_param: ctlplane_service_ips }
135               role_merged_configs:
136                 {%- for r in roles %}
137                 {{r.name}}: {get_param: [role_data, {{r.name}}, merged_config_settings]}
138                 {%- endfor %}
139             evaluate_env: false
140       always_update: true
141 # END service_workflow_tasks handling
142 {% endfor %}
143
144 {% for role in roles %}
145   # Post deployment steps for all roles
146   # A single config is re-applied with an incrementing step number
147   # {{role.name}} Role steps
148   {{role.name}}ArtifactsConfig:
149     type: ../puppet/deploy-artifacts.yaml
150
151   {{role.name}}ArtifactsDeploy:
152     type: OS::Heat::StructuredDeploymentGroup
153     properties:
154       servers:  {get_param: [servers, {{role.name}}]}
155       config: {get_resource: {{role.name}}ArtifactsConfig}
156
157   {{role.name}}HostPrepConfig:
158     type: OS::Heat::SoftwareConfig
159     properties:
160       group: ansible
161       options:
162         modulepath: /usr/share/ansible-modules
163       config:
164         str_replace:
165           template: _PLAYBOOK
166           params:
167             _PLAYBOOK:
168               - hosts: localhost
169                 connection: local
170                 vars:
171                   puppet_config: {get_param: [role_data, {{role.name}}, puppet_config]}
172                   docker_puppet_script: {get_file: ../docker/docker-puppet.py}
173                   docker_puppet_tasks: {get_param: [role_data, {{role.name}}, docker_puppet_tasks]}
174                   docker_startup_configs: {get_param: [role_data, {{role.name}}, docker_config]}
175                   kolla_config: {get_param: [role_data, {{role.name}}, kolla_config]}
176                   bootstrap_server_id: {get_param: [servers, {{primary_role_name}}, '0']}
177                   puppet_step_config: {get_param: [role_data, {{role.name}}, step_config]}
178                 tasks:
179                   # Join host_prep_tasks with the other per-host configuration
180                   yaql:
181                     expression: $.data.host_prep_tasks + $.data.template_tasks
182                     data:
183                       host_prep_tasks: {get_param: [role_data, {{role.name}}, host_prep_tasks]}
184                       template_tasks:
185 {%- raw %}
186                         # Write the manifest for baremetal puppet configuration
187                         - name: Create /var/lib/tripleo-config directory
188                           file: path=/var/lib/tripleo-config state=directory
189                         - name: Write the puppet step_config manifest
190                           copy: content="{{puppet_step_config}}" dest=/var/lib/tripleo-config/puppet_step_config.pp force=yes
191                         # this creates a JSON config file for our docker-puppet.py script
192                         - name: Create /var/lib/docker-puppet
193                           file: path=/var/lib/docker-puppet state=directory
194                         - name: Write docker-puppet-tasks json files
195                           copy: content="{{puppet_config | to_json}}" dest=/var/lib/docker-puppet/docker-puppet.json force=yes
196                         # FIXME: can we move docker-puppet somewhere so it's installed via a package?
197                         - name: Write docker-puppet.py
198                           copy: content="{{docker_puppet_script}}" dest=/var/lib/docker-puppet/docker-puppet.py force=yes
199                         # Here we are dumping all the docker container startup configuration data
200                         # so that we can have access to how they are started outside of heat
201                         # and docker-cmd.  This lets us create command line tools to test containers.
202                         # FIXME do we need the docker-container-startup-configs.json or is the new per-step
203                         # data consumed by paunch enough?
204                         - name: Write docker-container-startup-configs
205                           copy: content="{{docker_startup_configs | to_json}}" dest=/var/lib/docker-container-startup-configs.json force=yes
206                         - name: Write per-step docker-container-startup-configs
207                           copy: content="{{item.value|to_json}}" dest="/var/lib/tripleo-config/docker-container-startup-config-{{item.key}}.json" force=yes
208                           with_dict: "{{docker_startup_configs}}"
209                         - name: Create /var/lib/kolla/config_files directory
210                           file: path=/var/lib/kolla/config_files state=directory
211                         - name: Write kolla config json files
212                           copy: content="{{item.value|to_json}}" dest="{{item.key}}" force=yes
213                           with_dict: "{{kolla_config}}"
214                         ########################################################
215                         # Bootstrap tasks, only performed on bootstrap_server_id
216                         ########################################################
217                         - name: Clean /var/lib/docker-puppet/docker-puppet-tasks*.json files
218                           file:
219                             path: "{{item}}"
220                             state: absent
221                           with_fileglob:
222                             - /var/lib/docker-puppet/docker-puppet-tasks*.json
223                           when: deploy_server_id == bootstrap_server_id
224                         - name: Write docker-puppet-tasks json files
225                           copy: content="{{item.value|to_json}}" dest=/var/lib/docker-puppet/docker-puppet-tasks{{item.key.replace("step_", "")}}.json force=yes
226                           with_dict: "{{docker_puppet_tasks}}"
227                           when: deploy_server_id == bootstrap_server_id
228 {%- endraw %}
229
230   {{role.name}}HostPrepDeployment:
231     type: OS::Heat::SoftwareDeploymentGroup
232     properties:
233       servers: {get_param: [servers, {{role.name}}]}
234       config: {get_resource: {{role.name}}HostPrepConfig}
235
236   # BEGIN CONFIG STEPS
237
238   {{role.name}}PreConfig:
239     type: OS::TripleO::Tasks::{{role.name}}PreConfig
240     depends_on: {{role.name}}HostPrepDeployment
241     properties:
242       servers: {get_param: [servers, {{role.name}}]}
243       input_values:
244         update_identifier: {get_param: DeployIdentifier}
245
246   {% for step in range(1, deploy_steps_max) %}
247   {{role.name}}Deployment_Step{{step}}:
248     type: OS::TripleO::DeploymentSteps
249     depends_on:
250       - WorkflowTasks_Step{{step}}_Execution
251     # TODO(gfidente): the following if/else condition
252     # replicates what is already defined for the
253     # WorkflowTasks_StepX resource and can be remove
254     # if https://bugs.launchpad.net/heat/+bug/1700569
255     # is fixed.
256     {%- if step == 1 %}
257     {%- for dep in roles %}
258       - {{dep.name}}PreConfig
259       - {{dep.name}}ArtifactsDeploy
260     {%- endfor %}
261     {%- else %}
262     {%- for dep in roles %}
263       - {{dep.name}}Deployment_Step{{step -1}}
264     {%- endfor %}
265     {%- endif %}
266     properties:
267       name: {{role.name}}Deployment_Step{{step}}
268       servers: {get_param: [servers, {{role.name}}]}
269       config: {get_resource: RoleConfig}
270       input_values:
271         step: {{step}}
272         role_name: {{role.name}}
273         update_identifier: {get_param: DeployIdentifier}
274         bootstrap_server_id: {get_param: [servers, {{primary_role_name}}, '0']}
275         docker_puppet_debug: {get_param: DockerPuppetDebug}
276   {% endfor %}
277   # END CONFIG STEPS
278
279   # Note, this should be the last step to execute configuration changes.
280   # Ensure that all {{role.name}}ExtraConfigPost steps are executed
281   # after all the previous deployment steps.
282   {{role.name}}ExtraConfigPost:
283     depends_on:
284   {%- for dep in roles %}
285       - {{dep.name}}Deployment_Step5
286   {%- endfor %}
287     type: OS::TripleO::NodeExtraConfigPost
288     properties:
289         servers: {get_param: [servers, {{role.name}}]}
290
291   # The {{role.name}}PostConfig steps are in charge of
292   # quiescing all services, i.e. in the Controller case,
293   # we should run a full service reload.
294   {{role.name}}PostConfig:
295     type: OS::TripleO::Tasks::{{role.name}}PostConfig
296     depends_on:
297   {%- for dep in roles %}
298       - {{dep.name}}ExtraConfigPost
299   {%- endfor %}
300     properties:
301       servers:  {get_param: servers}
302       input_values:
303         update_identifier: {get_param: DeployIdentifier}
304
305
306 {% endfor %}
307
308 outputs:
309   RoleConfig:
310     description: Mapping of config data for all roles
311     value:
312       deploy_steps_tasks: {get_file: deploy-steps-tasks.yaml}
313       deploy_steps_playbook: |
314         - hosts: overcloud
315           tasks:
316 {%- for role in roles %}
317             - include: {{role.name}}/host_prep_tasks.yaml
318               when: role_name == '{{role.name}}'
319 {%- endfor %}
320             - include: deploy_steps_tasks.yaml
321               with_sequence: start=0 end={{deploy_steps_max-1}}
322               loop_control:
323                 loop_var: step
324       update_steps_tasks: |
325 {%- for role in roles %}
326             - include: {{role.name}}/update_tasks.yaml
327               when: role_name == '{{role.name}}'
328 {%- endfor %}
329       update_steps_playbook: |
330         - hosts: overcloud
331           serial: 1
332           tasks:
333             - include: update_steps_tasks.yaml
334               with_sequence: start=0 end={{update_steps_max-1}}
335               loop_control:
336                 loop_var: step
337             - include: deploy_steps_tasks.yaml
338               with_sequence: start=0 end={{deploy_steps_max-1}}
339               loop_control:
340                 loop_var: step
341       upgrade_steps_tasks: |
342 {%- for role in roles %}
343             - include: {{role.name}}/upgrade_tasks.yaml
344               when: role_name == '{{role.name}}'
345 {%- endfor %}
346       upgrade_steps_playbook: |
347         - hosts: overcloud
348           tasks:
349             - include: upgrade_steps_tasks.yaml
350               with_sequence: start=0 end={{upgrade_steps_max-1}}
351               loop_control:
352                 loop_var: step
353             - include: deploy_steps_tasks.yaml
354               with_sequence: start=0 end={{deploy_steps_max-1}}
355               loop_control:
356                 loop_var: step
357