c45a8a462a
We introduced a new Ansible role, tripleo-bootstrap: I560273be2ebe3a49ff37e3682222706939e5d879 This role will take care of preparing an environment that will deploy TripleO later. This patch aims to use execute this new role on all hosts. We don't gather_facts, (already gathered previously), we want to fail on any error and also the role will be executed on pre_deploy_steps tag. Change-Id: If9306473701a340d577bbe0a4a7dfee90be99c2f Depends-On: I560273be2ebe3a49ff37e3682222706939e5d879
535 lines
21 KiB
Django/Jinja
535 lines
21 KiB
Django/Jinja
# certain initialization steps (run in a container) will occur
|
|
# on the role marked as primary controller or the first role listed
|
|
{%- if enabled_roles is not defined or enabled_roles == [] -%}
|
|
# On upgrade certain roles can be disabled for operator driven upgrades
|
|
# See major_upgrade_steps.j2.yaml and post-upgrade.j2.yaml
|
|
{%- set enabled_roles = roles -%}
|
|
{%- set is_upgrade = false -%}
|
|
{%- else %}
|
|
{%- set is_upgrade = true -%}
|
|
{%- endif -%}
|
|
{%- set primary_role = [enabled_roles[0]] -%}
|
|
{%- for role in enabled_roles -%}
|
|
{%- if 'primary' in role.tags and 'controller' in role.tags -%}
|
|
{%- set _ = primary_role.pop() -%}
|
|
{%- set _ = primary_role.append(role) -%}
|
|
{%- endif -%}
|
|
{%- endfor -%}
|
|
{%- set primary_role_name = primary_role[0].name -%}
|
|
# primary role is: {{primary_role_name}}
|
|
{% set deploy_steps_max = 6 -%}
|
|
{% set update_steps_max = 6 -%}
|
|
{% set upgrade_steps_max = 6 -%}
|
|
|
|
heat_template_version: queens
|
|
|
|
description: >
|
|
Post-deploy configuration steps via puppet for all roles,
|
|
as defined in ../roles_data.yaml
|
|
|
|
parameters:
|
|
servers:
|
|
type: json
|
|
description: Mapping of Role name e.g Controller to a list of servers
|
|
stack_name:
|
|
type: string
|
|
description: Name of the topmost stack
|
|
role_data:
|
|
type: json
|
|
description: Mapping of Role name e.g Controller to the per-role data
|
|
DeployIdentifier:
|
|
default: ''
|
|
type: string
|
|
description: >
|
|
Setting this to a unique value will re-run any deployment tasks which
|
|
perform configuration on a Heat stack-update.
|
|
EndpointMap:
|
|
default: {}
|
|
description: Mapping of service endpoint -> protocol. Typically set
|
|
via parameter_defaults in the resource registry.
|
|
type: json
|
|
ConfigDebug:
|
|
default: false
|
|
description: Whether to run config management (e.g. Puppet) in debug mode.
|
|
type: boolean
|
|
DockerPuppetDebug:
|
|
type: string
|
|
default: ''
|
|
description: Set to True to enable debug logging with docker-puppet.py
|
|
DockerPuppetProcessCount:
|
|
type: number
|
|
default: 3
|
|
description: Number of concurrent processes to use when running docker-puppet to generate config files.
|
|
ctlplane_service_ips:
|
|
type: json
|
|
|
|
conditions:
|
|
{% for step in range(1, deploy_steps_max) %}
|
|
WorkflowTasks_Step{{step}}_Enabled:
|
|
or:
|
|
{%- for role in enabled_roles %}
|
|
- not:
|
|
equals:
|
|
- get_param: [role_data, {{role.name}}, workflow_tasks, step{{step}}]
|
|
- ''
|
|
- False
|
|
{%- endfor %}
|
|
{% endfor %}
|
|
|
|
resources:
|
|
|
|
RoleConfig:
|
|
type: OS::Heat::SoftwareConfig
|
|
properties:
|
|
group: ansible
|
|
options:
|
|
modulepath: /usr/share/ansible-modules
|
|
inputs:
|
|
- name: step
|
|
- name: role_name
|
|
- name: update_identifier
|
|
- name: bootstrap_server_id
|
|
- name: enable_debug
|
|
- name: docker_puppet_debug
|
|
- name: docker_puppet_process_count
|
|
config:
|
|
str_replace:
|
|
template: |
|
|
- hosts: localhost
|
|
connection: local
|
|
tasks:
|
|
_TASKS
|
|
params:
|
|
_TASKS: {get_file: deploy-steps-tasks.yaml}
|
|
|
|
ExternalDeployTasks:
|
|
type: OS::Heat::Value
|
|
properties:
|
|
type: comma_delimited_list
|
|
value:
|
|
yaql:
|
|
# processing from per-role unique tasks into globally unique tasks
|
|
expression: coalesce($.data, []).flatten().distinct()
|
|
data:
|
|
{%- for role in enabled_roles %}
|
|
- get_param: [role_data, {{role.name}}, external_deploy_tasks]
|
|
{%- endfor %}
|
|
|
|
ExternalPostDeployTasks:
|
|
type: OS::Heat::Value
|
|
properties:
|
|
type: comma_delimited_list
|
|
value:
|
|
yaql:
|
|
# processing from per-role unique tasks into globally unique tasks
|
|
expression: coalesce($.data, []).flatten().distinct()
|
|
data:
|
|
{%- for role in enabled_roles %}
|
|
- get_param: [role_data, {{role.name}}, external_post_deploy_tasks]
|
|
{%- endfor %}
|
|
|
|
{%- for step in range(1, deploy_steps_max) %}
|
|
# BEGIN workflow_tasks handling
|
|
WorkflowTasks_Step{{step}}:
|
|
type: OS::Mistral::Workflow
|
|
condition: WorkflowTasks_Step{{step}}_Enabled
|
|
depends_on:
|
|
{%- if step == 1 %}
|
|
{%- for dep in enabled_roles %}
|
|
- {{dep.name}}PreConfig
|
|
- {{dep.name}}ArtifactsDeploy
|
|
{%- endfor %}
|
|
{%- else %}
|
|
{%- for dep in enabled_roles %}
|
|
- {{dep.name}}Deployment_Step{{step -1}}
|
|
{%- endfor %}
|
|
{%- endif %}
|
|
properties:
|
|
name: {list_join: [".", ["tripleo", {get_param: stack_name}, "workflow_tasks", "step{{step}}"]]}
|
|
type: direct
|
|
tags:
|
|
- tripleo-heat-templates-managed
|
|
- {get_param: stack_name}
|
|
tasks:
|
|
yaql:
|
|
expression: $.data.where($ != '').select($.get('step{{step}}')).where($ != null).flatten()
|
|
data:
|
|
{%- for role in enabled_roles %}
|
|
- get_param: [role_data, {{role.name}}, workflow_tasks]
|
|
{%- endfor %}
|
|
|
|
WorkflowTasks_Step{{step}}_Execution:
|
|
type: OS::Mistral::ExternalResource
|
|
condition: WorkflowTasks_Step{{step}}_Enabled
|
|
depends_on: WorkflowTasks_Step{{step}}
|
|
properties:
|
|
actions:
|
|
CREATE:
|
|
workflow: { get_resource: WorkflowTasks_Step{{step}} }
|
|
params:
|
|
env:
|
|
service_ips: { get_param: ctlplane_service_ips }
|
|
role_merged_configs:
|
|
{%- for r in roles %}
|
|
{{r.name}}: {get_param: [role_data, {{r.name}}, merged_config_settings]}
|
|
{%- endfor %}
|
|
evaluate_env: false
|
|
UPDATE:
|
|
workflow: { get_resource: WorkflowTasks_Step{{step}} }
|
|
params:
|
|
env:
|
|
service_ips: { get_param: ctlplane_service_ips }
|
|
role_merged_configs:
|
|
{%- for r in roles %}
|
|
{{r.name}}: {get_param: [role_data, {{r.name}}, merged_config_settings]}
|
|
{%- endfor %}
|
|
evaluate_env: false
|
|
always_update: true
|
|
# END workflow_tasks handling
|
|
{% endfor %}
|
|
|
|
BootstrapServerId:
|
|
type: OS::Heat::Value
|
|
properties:
|
|
value:
|
|
yaql:
|
|
expression: $.data.items().orderBy($[0]).first()[1]
|
|
data: {get_param: [servers, {{primary_role_name}}]}
|
|
|
|
# Artifacts config and HostPrepConfig is done on all roles, not only
|
|
# enabled_roles, because on upgrade we need to write the json files
|
|
# for the operator driven upgrade scripts (the ansible steps consume them)
|
|
{% for role in roles %}
|
|
# Prepare host tasks for {{role.name}}
|
|
{{role.name}}ArtifactsConfig:
|
|
type: ../puppet/deploy-artifacts.yaml
|
|
|
|
{{role.name}}ArtifactsDeploy:
|
|
type: OS::Heat::StructuredDeploymentGroup
|
|
properties:
|
|
name: {{role.name}}ArtifactsDeploy
|
|
servers: {get_param: [servers, {{role.name}}]}
|
|
config: {get_resource: {{role.name}}ArtifactsConfig}
|
|
|
|
{{role.name}}HostPrepConfig:
|
|
type: OS::Heat::SoftwareConfig
|
|
properties:
|
|
group: ansible
|
|
options:
|
|
modulepath: /usr/share/ansible-modules
|
|
config:
|
|
str_replace:
|
|
template: _PLAYBOOK
|
|
params:
|
|
_PLAYBOOK:
|
|
- hosts: localhost
|
|
connection: local
|
|
vars:
|
|
puppet_config: {get_param: [role_data, {{role.name}}, puppet_config]}
|
|
docker_puppet_script: {get_file: ../docker/docker-puppet.py}
|
|
docker_puppet_tasks: {get_param: [role_data, {{role.name}}, docker_puppet_tasks]}
|
|
docker_startup_configs: {get_param: [role_data, {{role.name}}, docker_config]}
|
|
kolla_config: {get_param: [role_data, {{role.name}}, kolla_config]}
|
|
bootstrap_server_id: {get_attr: [BootstrapServerId, value]}
|
|
puppet_step_config: {get_param: [role_data, {{role.name}}, step_config]}
|
|
docker_config_scripts: {get_param: [role_data, {{role.name}}, docker_config_scripts]}
|
|
tasks:
|
|
# Join host_prep_tasks with the other per-host configuration
|
|
list_concat:
|
|
{%- if is_upgrade|default(false) and role.disable_upgrade_deployment|default(false) %}
|
|
- []
|
|
{%- else %}
|
|
- {get_param: [role_data, {{role.name}}, host_prep_tasks]}
|
|
{%- endif %}
|
|
-
|
|
# Write the manifest for baremetal puppet configuration
|
|
- name: Create /var/lib/tripleo-config directory
|
|
file: path=/var/lib/tripleo-config state=directory setype=svirt_sandbox_file_t selevel=s0 recurse=true
|
|
- name: Write the puppet step_config manifest
|
|
copy: content="{{ '{{' }}puppet_step_config{{ '}}' }}" dest=/var/lib/tripleo-config/puppet_step_config.pp force=yes mode=0600
|
|
# this creates a JSON config file for our docker-puppet.py script
|
|
- name: Create /var/lib/docker-puppet
|
|
file: path=/var/lib/docker-puppet state=directory setype=svirt_sandbox_file_t selevel=s0 recurse=true
|
|
- name: Write docker-puppet-tasks json files
|
|
copy: content="{{ '{{' }}puppet_config | to_json{{ '}}' }}" dest=/var/lib/docker-puppet/docker-puppet.json force=yes mode=0600
|
|
# FIXME: can we move docker-puppet somewhere so it's installed via a package?
|
|
- name: Write docker-puppet.py
|
|
copy: content="{{ '{{' }}docker_puppet_script{{ '}}' }}" dest=/var/lib/docker-puppet/docker-puppet.py force=yes mode=0600
|
|
- name: Create /var/lib/docker-config-scripts
|
|
file: path=/var/lib/docker-config-scripts state=directory
|
|
- name: Write docker config scripts
|
|
copy: content="{{ '{{' }}item.value.content{{ '}}' }}" dest="/var/lib/docker-config-scripts/{{ '{{' }}item.key{{ '}}' }}" force=yes mode="{{ '{{' }}item.value.mode|default('0600', true){{ '}}' }}"
|
|
with_dict: "{{ '{{' }}docker_config_scripts{{ '}}' }}"
|
|
# Here we are dumping all the docker container startup configuration data
|
|
# so that we can have access to how they are started outside of heat
|
|
# and docker-cmd. This lets us create command line tools to test containers.
|
|
# FIXME do we need the docker-container-startup-configs.json or is the new per-step
|
|
# data consumed by paunch enough?
|
|
- name: Write docker-container-startup-configs
|
|
copy: content="{{ '{{' }}docker_startup_configs | to_json{{ '}}' }}" dest=/var/lib/docker-container-startup-configs.json force=yes mode=0600
|
|
- name: Write per-step docker-container-startup-configs
|
|
copy: content="{{ '{{' }}item.value|to_json{{ '}}' }}" dest="/var/lib/tripleo-config/docker-container-startup-config-{{ '{{' }}item.key{{ '}}' }}.json" force=yes mode=0600
|
|
with_dict: "{{ '{{' }}docker_startup_configs{{ '}}' }}"
|
|
- name: Create /var/lib/kolla/config_files directory
|
|
file: path=/var/lib/kolla/config_files state=directory setype=svirt_sandbox_file_t selevel=s0 recurse=true
|
|
- name: Write kolla config json files
|
|
copy: content="{{ '{{' }}item.value|to_json{{ '}}' }}" dest="{{ '{{' }}item.key{{ '}}' }}" force=yes mode=0600
|
|
with_dict: "{{ '{{' }}kolla_config{{ '}}' }}"
|
|
########################################################
|
|
# Bootstrap tasks, only performed on bootstrap_server_id
|
|
########################################################
|
|
- name: Clean /var/lib/docker-puppet/docker-puppet-tasks*.json files
|
|
file:
|
|
path: "{{ '{{' }}item{{ '}}' }}"
|
|
state: absent
|
|
with_fileglob:
|
|
- /var/lib/docker-puppet/docker-puppet-tasks*.json
|
|
when: deploy_server_id == bootstrap_server_id
|
|
- name: Write docker-puppet-tasks json files
|
|
copy: content="{{ '{{' }}item.value|to_json{{ '}}' }}" dest=/var/lib/docker-puppet/docker-puppet-tasks{{ '{{' }}item.key.replace("step_", ""){{ '}}' }}.json force=yes mode=0600
|
|
with_dict: "{{ '{{' }}docker_puppet_tasks{{ '}}' }}"
|
|
when: deploy_server_id == bootstrap_server_id
|
|
|
|
{{role.name}}HostPrepDeployment:
|
|
type: OS::Heat::SoftwareDeploymentGroup
|
|
properties:
|
|
name: {{role.name}}HostPrepDeployment
|
|
servers: {get_param: [servers, {{role.name}}]}
|
|
config: {get_resource: {{role.name}}HostPrepConfig}
|
|
{% endfor %}
|
|
|
|
# BEGIN CONFIG STEPS, only on enabled_roles
|
|
{%- for role in enabled_roles %}
|
|
{{role.name}}PreConfig:
|
|
type: OS::TripleO::Tasks::{{role.name}}PreConfig
|
|
depends_on: {{role.name}}HostPrepDeployment
|
|
properties:
|
|
servers: {get_param: [servers, {{role.name}}]}
|
|
input_values:
|
|
update_identifier: {get_param: DeployIdentifier}
|
|
|
|
# Deployment steps for {{role.name}}
|
|
# A single config is re-applied with an incrementing step number
|
|
{% for step in range(1, deploy_steps_max) %}
|
|
{{role.name}}Deployment_Step{{step}}:
|
|
type: OS::TripleO::DeploymentSteps
|
|
depends_on:
|
|
- WorkflowTasks_Step{{step}}_Execution
|
|
# TODO(gfidente): the following if/else condition
|
|
# replicates what is already defined for the
|
|
# WorkflowTasks_StepX resource and can be remove
|
|
# if https://bugs.launchpad.net/heat/+bug/1700569
|
|
# is fixed.
|
|
{%- if step == 1 %}
|
|
{%- for dep in enabled_roles %}
|
|
- {{dep.name}}PreConfig
|
|
- {{dep.name}}ArtifactsDeploy
|
|
{%- endfor %}
|
|
{%- else %}
|
|
{%- for dep in enabled_roles %}
|
|
- {{dep.name}}Deployment_Step{{step -1}}
|
|
{%- endfor %}
|
|
{%- endif %}
|
|
properties:
|
|
name: {{role.name}}Deployment_Step{{step}}
|
|
servers: {get_param: [servers, {{role.name}}]}
|
|
config: {get_resource: RoleConfig}
|
|
input_values:
|
|
step: {{step}}
|
|
role_name: {{role.name}}
|
|
update_identifier: {get_param: DeployIdentifier}
|
|
bootstrap_server_id: {get_attr: [BootstrapServerId, value]}
|
|
enable_debug: {get_param: ConfigDebug}
|
|
docker_puppet_debug: {get_param: DockerPuppetDebug}
|
|
docker_puppet_process_count: {get_param: DockerPuppetProcessCount}
|
|
{% endfor %}
|
|
# END CONFIG STEPS
|
|
|
|
# Note, this should be the last step to execute configuration changes.
|
|
# Ensure that all {{role.name}}ExtraConfigPost steps are executed
|
|
# after all the previous deployment steps.
|
|
{{role.name}}ExtraConfigPost:
|
|
depends_on:
|
|
{%- for dep in enabled_roles %}
|
|
- {{dep.name}}Deployment_Step5
|
|
{%- endfor %}
|
|
type: OS::TripleO::NodeExtraConfigPost
|
|
properties:
|
|
servers: {get_param: [servers, {{role.name}}]}
|
|
|
|
# The {{role.name}}PostConfig steps are in charge of
|
|
# quiescing all services, i.e. in the Controller case,
|
|
# we should run a full service reload.
|
|
{{role.name}}PostConfig:
|
|
type: OS::TripleO::Tasks::{{role.name}}PostConfig
|
|
depends_on:
|
|
{%- for dep in enabled_roles %}
|
|
- {{dep.name}}ExtraConfigPost
|
|
{%- endfor %}
|
|
properties:
|
|
servers: {get_param: servers}
|
|
input_values:
|
|
update_identifier: {get_param: DeployIdentifier}
|
|
|
|
|
|
{% endfor %}
|
|
|
|
outputs:
|
|
RoleConfig:
|
|
description: Mapping of config data for all roles
|
|
value:
|
|
common_deploy_steps_tasks: {get_file: deploy-steps-tasks.yaml}
|
|
deploy_steps_playbook:
|
|
str_replace:
|
|
params:
|
|
BOOTSTRAP_SERVER_ID: {get_attr: [BootstrapServerId, value]}
|
|
template: |
|
|
- hosts: undercloud
|
|
name: Gather facts undercloud
|
|
gather_facts: yes
|
|
become: false
|
|
tags:
|
|
- facts
|
|
- hosts: overcloud
|
|
name: Gather facts overcloud
|
|
gather_facts: yes
|
|
tags:
|
|
- facts
|
|
- hosts: overcloud
|
|
name: Bootstrap TripleO servers
|
|
gather_facts: no
|
|
any_errors_fatal: yes
|
|
roles:
|
|
- tripleo-bootstrap
|
|
tags:
|
|
- bootstrap
|
|
- hosts: overcloud
|
|
name: Server deployments
|
|
gather_facts: no
|
|
any_errors_fatal: yes
|
|
tasks:
|
|
{%- for role in roles %}
|
|
- include: {{role.name}}/deployments.yaml
|
|
vars:
|
|
force: false
|
|
when: role_name == '{{role.name}}'
|
|
with_items: "{{ '{{' }} {{role.name}}_pre_deployments|default([]) {{ '}}' }}"
|
|
{%- endfor %}
|
|
tags:
|
|
- overcloud
|
|
- pre_deploy_steps
|
|
- hosts: overcloud
|
|
name: Host prep steps
|
|
gather_facts: no
|
|
any_errors_fatal: yes
|
|
vars:
|
|
bootstrap_server_id: BOOTSTRAP_SERVER_ID
|
|
tasks:
|
|
{%- for role in roles %}
|
|
- include: {{role.name}}/host_prep_tasks.yaml
|
|
when: role_name == '{{role.name}}'
|
|
{%- endfor %}
|
|
tags:
|
|
- overcloud
|
|
- host_prep_steps
|
|
{%- for step in range(1,deploy_steps_max) %}
|
|
- hosts: undercloud
|
|
name: External deployment step {{step}}
|
|
gather_facts: no
|
|
any_errors_fatal: yes
|
|
become: false
|
|
vars:
|
|
step: '{{step}}'
|
|
tasks:
|
|
- include: external_deploy_steps_tasks.yaml
|
|
tags:
|
|
- external
|
|
- external_deploy_steps
|
|
- hosts: overcloud
|
|
name: Overcloud deploy step tasks for {{step}}
|
|
gather_facts: no
|
|
any_errors_fatal: yes
|
|
# FIXME(shardy) - it would be nice to use strategy: free to
|
|
# allow the tasks per-step to run in parallel on each role,
|
|
# but that doesn't work with any_errors_fatal: yes
|
|
vars:
|
|
bootstrap_server_id: BOOTSTRAP_SERVER_ID
|
|
step: '{{step}}'
|
|
tasks:
|
|
{%- for role in roles %}
|
|
- include: {{role.name}}/deploy_steps_tasks.yaml
|
|
when: role_name == '{{role.name}}'
|
|
{%- endfor %}
|
|
tags:
|
|
- overcloud
|
|
- deploy_steps
|
|
- hosts: overcloud
|
|
name: Overcloud common deploy step tasks {{step}}
|
|
gather_facts: no
|
|
any_errors_fatal: yes
|
|
vars:
|
|
bootstrap_server_id: BOOTSTRAP_SERVER_ID
|
|
step: '{{step}}'
|
|
tasks:
|
|
- include: common_deploy_steps_tasks.yaml
|
|
tags:
|
|
- overcloud
|
|
- deploy_steps
|
|
{%- endfor %}
|
|
- hosts: overcloud
|
|
name: Server Post Deployments
|
|
gather_facts: no
|
|
any_errors_fatal: yes
|
|
tasks:
|
|
{%- for role in roles %}
|
|
- include: {{role.name}}/deployments.yaml
|
|
vars:
|
|
force: false
|
|
when: role_name == '{{role.name}}'
|
|
with_items: "{{ '{{' }} {{role.name}}_post_deployments|default([]) {{ '}}' }}"
|
|
tags:
|
|
- overcloud
|
|
- post_deploy_steps
|
|
{%- endfor %}
|
|
- hosts: undercloud
|
|
name: External deployment Post Deploy tasks
|
|
gather_facts: no
|
|
any_errors_fatal: yes
|
|
become: false
|
|
tasks:
|
|
- include: external_post_deploy_steps_tasks.yaml
|
|
tags:
|
|
- external
|
|
- external_deploy_steps
|
|
external_deploy_steps_tasks: {get_attr: [ExternalDeployTasks, value]}
|
|
external_post_deploy_steps_tasks: {get_attr: [ExternalPostDeployTasks, value]}
|
|
update_steps_tasks: |
|
|
{%- for role in roles %}
|
|
- include: {{role.name}}/update_tasks.yaml
|
|
when: role_name == '{{role.name}}'
|
|
{%- endfor %}
|
|
update_steps_playbook: |
|
|
- hosts: overcloud
|
|
serial: 1
|
|
tasks:
|
|
- include: update_steps_tasks.yaml
|
|
with_sequence: start=1 end={{update_steps_max-1}}
|
|
loop_control:
|
|
loop_var: step
|
|
- include: deploy_steps_tasks.yaml
|
|
with_sequence: start=1 end={{deploy_steps_max-1}}
|
|
loop_control:
|
|
loop_var: step
|
|
upgrade_steps_tasks: |
|
|
{%- for role in roles %}
|
|
- include: {{role.name}}/upgrade_tasks.yaml
|
|
when: role_name == '{{role.name}}'
|
|
{%- endfor %}
|
|
upgrade_steps_playbook: |
|
|
- hosts: overcloud
|
|
tasks:
|
|
- include: upgrade_steps_tasks.yaml
|
|
with_sequence: start=1 end={{upgrade_steps_max-1}}
|
|
loop_control:
|
|
loop_var: step
|