{"heat_template_version": "wallaby", "description": "OpenStack containerized Redis services\n", "parameters": {"ContainerRedisImage": {"description": "image", "type": "string", "tags": ["role_specific"]}, "ContainerRedisConfigImage": {"description": "The container image to use for the redis config_volume", "type": "string", "tags": ["role_specific"]}, "ClusterCommonTag": {"default": false, "description": "When set to false, a pacemaker service is configured to use a floating tag for its container image name, e.g. 'REGISTRY/NAMESPACE/IMAGENAME:pcmklatest'. When set to true, the service uses a floating prefix as well, e.g. 'cluster.common.tag/IMAGENAME:pcmklatest'.", "type": "boolean"}, "ClusterFullTag": {"default": true, "description": "When set to true, the pacemaker service uses a fully constant tag for its container image name, e.g. 'cluster.common.tag/SERVICENAME:pcmklatest'.", "type": "boolean"}, "EndpointMap": {"default": {}, "description": "Mapping of service endpoint -> protocol. Typically set via parameter_defaults in the resource registry.", "type": "json"}, "ServiceData": {"default": {}, "description": "Dictionary packing service data", "type": "json"}, "ServiceNetMap": {"default": {}, "description": "Mapping of service_name -> network name. Typically set via parameter_defaults in the resource registry. Use parameter_merge_strategies to merge it with the defaults.", "type": "json"}, "RoleName": {"default": "", "description": "Role name on which the service is applied", "type": "string"}, "RoleParameters": {"default": {}, "description": "Parameters specific to the role", "type": "json"}, "ConfigDebug": {"default": false, "description": "Whether to run config management (e.g. Puppet) in debug mode.", "type": "boolean"}, "EnableInternalTLS": {"type": "boolean", "default": false}, "RedisIPv6": {"default": false, "description": "Enable IPv6 in Redis", "type": "boolean"}, "ContainerCli": {"type": "string", "default": "podman", "description": "CLI tool used to manage containers.", "constraints": [{"allowed_values": ["docker", "podman"]}]}, "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.\n"}}, "parameter_groups": [{"label": "deprecated", "description": "The following parameters are deprecated and will be removed. They should not\nbe relied on for new deployments. If you have concerns regarding deprecated\nparameters, please contact the TripleO development team on IRC or the\nOpenStack mailing list.\n", "parameters": ["RedisIPv6"]}], "conditions": {"is_ipv6": {"equals": [{"get_param": ["ServiceData", "net_ip_version_map", {"get_param": ["ServiceNetMap", "RedisNetwork"]}]}, 6]}}, "resources": {"ContainersCommon": {"type": "file:///usr/share/openstack-tripleo-heat-templates/deployment/containers-common.yaml"}, "RedisBase": {"type": "file:///usr/share/openstack-tripleo-heat-templates/deployment/database/redis-container-puppet.yaml", "properties": {"EndpointMap": {"get_param": "EndpointMap"}, "ServiceData": {"get_param": "ServiceData"}, "ServiceNetMap": {"get_param": "ServiceNetMap"}, "RoleName": {"get_param": "RoleName"}, "RoleParameters": {"get_param": "RoleParameters"}}}, "RoleParametersValue": {"type": "OS::Heat::Value", "properties": {"type": "json", "value": {"map_replace": [{"map_replace": [{"ContainerRedisImage": "ContainerRedisImage", "ContainerRedisConfigImage": "ContainerRedisConfigImage"}, {"values": {"get_param": ["RoleParameters"]}}]}, {"values": {"ContainerRedisImage": {"get_param": "ContainerRedisImage"}, "ContainerRedisConfigImage": {"get_param": "ContainerRedisConfigImage"}}}]}}}}, "outputs": {"role_data": {"description": "Role data for the Redis API role.", "value": {"service_name": "redis", "firewall_rules": {"108 redis-bundle": {"dport": [3124, 6379, 26379]}}, "config_settings": {"map_merge": [{"get_attr": ["RedisBase", "role_data", "config_settings"]}, {"redis::service_manage": false, "redis::notify_service": false, "redis::managed_by_cluster_manager": true, "tripleo::profile::pacemaker::database::redis_bundle::redis_docker_image": {"if": [{"get_param": "ClusterFullTag"}, "cluster.common.tag/redis:pcmklatest", {"yaql": {"data": {"if": [{"get_param": "ClusterCommonTag"}, {"yaql": {"data": {"get_attr": ["RoleParametersValue", "value", "ContainerRedisImage"]}, "expression": "concat(\"cluster.common.tag/\", $.data.rightSplit(separator => \"/\", maxSplits => 1)[1])"}}, {"get_attr": ["RoleParametersValue", "value", "ContainerRedisImage"]}]}, "expression": "concat($.data.rightSplit(separator => \":\", maxSplits => 1)[0], \":pcmklatest\")"}}]}, "tripleo::profile::pacemaker::database::redis_bundle::control_port": 3124, "tripleo::profile::pacemaker::database::redis_bundle::container_backend": {"get_param": "ContainerCli"}, "tripleo::profile::pacemaker::database::redis_bundle::force_ocf": true, "tripleo::stunnel::manage_service": false, "tripleo::stunnel::foreground": "yes", "tripleo::profile::pacemaker::database::redis_bundle::tls_proxy_bind_ip": {"str_replace": {"template": "%{hiera('$NETWORK')}", "params": {"$NETWORK": {"get_param": ["ServiceNetMap", "RedisNetwork"]}}}}, "tripleo::profile::pacemaker::database::redis_bundle::tls_proxy_fqdn": {"str_replace": {"template": "%{hiera('fqdn_$NETWORK')}", "params": {"$NETWORK": {"get_param": ["ServiceNetMap", "RedisNetwork"]}}}}, "tripleo::profile::pacemaker::database::redis_bundle::tls_proxy_port": 6379, "tripleo::profile::pacemaker::database::redis::tls_proxy_bind_ip": {"str_replace": {"template": "%{hiera('$NETWORK')}", "params": {"$NETWORK": {"get_param": ["ServiceNetMap", "RedisNetwork"]}}}}, "tripleo::profile::pacemaker::database::redis::tls_proxy_fqdn": {"str_replace": {"template": "%{hiera('fqdn_$NETWORK')}", "params": {"$NETWORK": {"get_param": ["ServiceNetMap", "RedisNetwork"]}}}}, "tripleo::profile::pacemaker::database::redis::tls_proxy_port": 6379}, {"if": [{"get_param": "EnableInternalTLS"}, {"redis::extra_config_file": "/etc/redis-tls.conf", "tripleo::profile::pacemaker::database::redis_bundle::extra_config_file": "/etc/redis-tls.conf", "tripleo::profile::pacemaker::database::redis_bundle::tls_tunnel_base_port": 6660, "tripleo::profile::pacemaker::database::redis_bundle::tls_tunnel_local_name": {"if": ["is_ipv6", "::1", "127.0.0.1"]}}]}]}, "service_config_settings": {"get_attr": ["RedisBase", "role_data", "service_config_settings"]}, "puppet_config": {"config_volume": "redis", "puppet_tags": "exec", "step_config": "Exec <| title == 'systemd-reload-redis' |> { unless => 'true' }\ninclude tripleo::profile::pacemaker::database::redis_bundle\n", "config_image": {"get_attr": ["RoleParametersValue", "value", "ContainerRedisConfigImage"]}}, "kolla_config": {"/var/lib/kolla/config_files/redis.json": {"command": "/usr/sbin/pacemaker_remoted", "config_files": [{"dest": "/etc/libqb/force-filesystem-sockets", "source": "/dev/null", "owner": "root", "perm": "0644"}, {"source": "/var/lib/kolla/config_files/src/*", "dest": "/", "merge": true, "preserve_properties": true, "optional": true}], "permissions": [{"path": "/run/redis", "owner": "redis:redis", "recurse": true}, {"path": "/var/lib/redis", "owner": "redis:redis", "recurse": true}, {"path": "/var/log/redis", "owner": "redis:redis", "recurse": true}]}, "/var/lib/kolla/config_files/redis_tls_proxy.json": {"command": {"str_replace": {"template": "bash -c $* -- eval /wait-port-and-run.sh $(hiera fqdn_$NETWORK) 6379 stunnel /etc/stunnel/stunnel.conf", "params": {"$NETWORK": {"get_param": ["ServiceNetMap", "RedisNetwork"]}}}}, "config_files": [{"source": "/var/lib/kolla/config_files/src/*", "dest": "/", "merge": true, "preserve_properties": true}, {"source": "/var/lib/kolla/config_files/src-tls/*", "dest": "/", "merge": true, "optional": true, "preserve_properties": true}], "permissions": [{"path": "/etc/pki/tls/certs/redis.crt", "owner": "root:root", "perm": "0600", "optional": true}, {"path": "/etc/pki/tls/private/redis.key", "owner": "root:root", "perm": "0600", "optional": true}]}}, "container_config_scripts": {"get_attr": ["ContainersCommon", "container_config_scripts"]}, "docker_config": {"step_1": {"if": [{"get_param": "EnableInternalTLS"}, {"redis_tls_proxy": {"start_order": 0, "image": {"get_attr": ["RoleParametersValue", "value", "ContainerRedisImage"]}, "net": "host", "user": "root", "restart": "always", "volumes": {"list_concat": [{"get_attr": ["ContainersCommon", "volumes"]}, ["/var/lib/kolla/config_files/redis_tls_proxy.json:/var/lib/kolla/config_files/config.json:ro", "/var/lib/config-data/puppet-generated/redis:/var/lib/kolla/config_files/src:ro", "/etc/pki/tls/certs/redis.crt:/var/lib/kolla/config_files/src-tls/etc/pki/tls/certs/redis.crt:ro", "/etc/pki/tls/private/redis.key:/var/lib/kolla/config_files/src-tls/etc/pki/tls/private/redis.key:ro", "/var/lib/container-config-scripts/wait-port-and-run.sh:/wait-port-and-run.sh:ro"]]}, "environment": {"KOLLA_CONFIG_STRATEGY": "COPY_ALWAYS"}}}]}}, "metadata_settings": {"get_attr": ["RedisBase", "role_data", "metadata_settings"]}, "external_deploy_tasks": {"get_attr": ["RedisBase", "role_data", "external_deploy_tasks"]}, "host_prep_tasks": [{"name": "create persistent directories", "file": {"path": "{{ item.path }}", "state": "directory", "setype": "{{ item.setype }}", "mode": "{{ item.mode|default(omit) }}"}, "with_items": [{"path": "/var/lib/redis", "setype": "container_file_t"}, {"path": "/var/log/containers/redis", "setype": "container_file_t", "mode": "0750"}, {"path": "/run/redis", "setype": "container_file_t"}]}, {"name": "ensure /run/redis is present upon reboot", "copy": {"dest": "/etc/tmpfiles.d/run-redis.conf", "content": "d /run/redis 0755 root root - -\n"}}], "deploy_steps_tasks": {"list_concat": [{"get_attr": ["RedisBase", "role_data", "deploy_steps_tasks"]}, [{"name": "Redis tag container image for pacemaker", "when": "step|int == 1", "import_role": {"name": "tripleo_container_tag"}, "vars": {"container_image": {"get_attr": ["RoleParametersValue", "value", "ContainerRedisImage"]}, "container_image_latest": {"if": [{"get_param": "ClusterFullTag"}, "cluster.common.tag/redis:pcmklatest", {"yaql": {"data": {"if": [{"get_param": "ClusterCommonTag"}, {"yaql": {"data": {"get_attr": ["RoleParametersValue", "value", "ContainerRedisImage"]}, "expression": "concat(\"cluster.common.tag/\", $.data.rightSplit(separator => \"/\", maxSplits => 1)[1])"}}, {"get_attr": ["RoleParametersValue", "value", "ContainerRedisImage"]}]}, "expression": "concat($.data.rightSplit(separator => \":\", maxSplits => 1)[0], \":pcmklatest\")"}}]}}}, {"name": "Redis HA Wrappers Step", "when": "step|int == 2", "block": [{"name": "Redis puppet bundle", "import_role": {"name": "tripleo_ha_wrapper"}, "vars": {"tripleo_ha_wrapper_service_name": "redis", "tripleo_ha_wrapper_resource_name": "redis", "tripleo_ha_wrapper_bundle_name": "redis-bundle", "tripleo_ha_wrapper_resource_state": "Slave Master", "tripleo_ha_wrapper_puppet_config_volume": "redis", "tripleo_ha_wrapper_puppet_execute": "include ::tripleo::profile::base::pacemaker; include ::tripleo::profile::pacemaker::database::redis_bundle", "tripleo_ha_wrapper_puppet_tags": "pacemaker::resource::bundle,pacemaker::property,pacemaker::resource::ocf,pacemaker::constraint::order,pacemaker::constraint::colocation", "tripleo_ha_wrapper_puppet_debug": {"get_param": "ConfigDebug"}, "tripleo_ha_wrapper_config_suffix": ".previous_run"}}]}]]}, "external_update_tasks": {"list_concat": [{"get_attr": ["RedisBase", "role_data", "external_update_tasks"]}, [{"when": "step|int == 1", "tags": "ha_image_update", "block": [{"block": [{"name": "Get redis image from pacemaker", "become": true, "register": "xmllint_pcmk_redis_image", "shell": "xmllint --xpath \"string(//bundle[@id='redis-bundle']/podman/@image)\" /var/lib/pacemaker/cib/cib.xml"}, {"name": "Get container redis image", "set_fact": {"redis_image": {"get_attr": ["RoleParametersValue", "value", "ContainerRedisImage"]}, "redis_image_latest": {"if": [{"get_param": "ClusterFullTag"}, "cluster.common.tag/redis:pcmklatest", {"yaql": {"data": {"if": [{"get_param": "ClusterCommonTag"}, {"yaql": {"data": {"get_attr": ["RoleParametersValue", "value", "ContainerRedisImage"]}, "expression": "concat(\"cluster.common.tag/\", $.data.rightSplit(separator => \"/\", maxSplits => 1)[1])"}}, {"get_attr": ["RoleParametersValue", "value", "ContainerRedisImage"]}]}, "expression": "concat($.data.rightSplit(separator => \":\", maxSplits => 1)[0], \":pcmklatest\")"}}]}, "pcmk_redis_image": "{{xmllint_pcmk_redis_image.stdout}}"}}], "delegate_to": "{{ (groups[\"redis\"] | difference(groups[\"excluded_overcloud\"]))[0] }}"}, {"name": "redis temporary pacemaker container tag in case of image switch", "become": true, "import_role": {"name": "tripleo_ha_image_update"}, "vars": {"tripleo_ha_image_update_node_names": "{{ groups[\"redis\"] | difference(groups[\"excluded_overcloud\"]) }}", "tripleo_ha_image_update_bundle": "redis-bundle", "tripleo_ha_image_update_new_image": "{{redis_image_latest}}", "tripleo_ha_image_update_old_image": "{{pcmk_redis_image}}"}, "when": ["(pcmk_redis_image != \"\")", "(pcmk_redis_image != redis_image_latest)"]}]}]]}, "update_tasks": [{"block": [{"name": "Get redis image from pacemaker", "become": true, "register": "xmllint_pcmk_redis_image", "shell": "xmllint --xpath \"string(//bundle[@id='redis-bundle']/podman/@image)\" /var/lib/pacemaker/cib/cib.xml"}, {"name": "Get container redis image", "set_fact": {"redis_image": {"get_attr": ["RoleParametersValue", "value", "ContainerRedisImage"]}, "redis_image_latest": {"if": [{"get_param": "ClusterFullTag"}, "cluster.common.tag/redis:pcmklatest", {"yaql": {"data": {"if": [{"get_param": "ClusterCommonTag"}, {"yaql": {"data": {"get_attr": ["RoleParametersValue", "value", "ContainerRedisImage"]}, "expression": "concat(\"cluster.common.tag/\", $.data.rightSplit(separator => \"/\", maxSplits => 1)[1])"}}, {"get_attr": ["RoleParametersValue", "value", "ContainerRedisImage"]}]}, "expression": "concat($.data.rightSplit(separator => \":\", maxSplits => 1)[0], \":pcmklatest\")"}}]}, "pcmk_redis_image": "{{xmllint_pcmk_redis_image.stdout}}"}}], "when": "(step|int == 0 or step|int == 2)"}, {"name": "Check for update of redis container image name", "when": "step|int == 0", "assert": {"that": "pcmk_redis_image == redis_image_latest", "fail_msg": "redis image change detected, run overcloud external-update --tags ha_image_update first"}}, {"name": "redis_pacemaker_puppet_tmpfile_cleanup", "when": "step|int == 1", "block": [{"name": "Clean old tmpfile configuration", "file": {"path": "/etc/tmpfiles.d/var-run-redis.conf", "state": "absent"}}]}, {"name": "Tear-down non-HA redis container", "when": ["step|int == 1"], "block": [{"name": "Remove non-HA redis container", "include_role": {"name": "tripleo_container_rm"}, "vars": {"tripleo_container_cli": "{{ container_cli }}", "tripleo_containers_to_rm": ["redis"]}}]}, {"name": "Redis fetch and retag container image for pacemaker", "when": "step|int == 2", "block": [{"name": "Retag pcmklatest to latest redis image", "include_role": {"name": "tripleo_container_tag"}, "vars": {"container_image": "{{redis_image}}", "container_image_latest": "{{redis_image_latest}}"}}]}], "post_update_tasks": [{"name": "Redis bundle post update", "when": "step|int == 1", "block": [{"name": "Redis puppet bundle", "import_role": {"name": "tripleo_ha_wrapper"}, "vars": {"tripleo_ha_wrapper_service_name": "redis", "tripleo_ha_wrapper_resource_name": "redis", "tripleo_ha_wrapper_bundle_name": "redis-bundle", "tripleo_ha_wrapper_resource_state": "Slave Master", "tripleo_ha_wrapper_puppet_config_volume": "redis", "tripleo_ha_wrapper_puppet_execute": "include ::tripleo::profile::base::pacemaker; include ::tripleo::profile::pacemaker::database::redis_bundle", "tripleo_ha_wrapper_puppet_tags": "pacemaker::resource::bundle,pacemaker::property,pacemaker::resource::ocf,pacemaker::constraint::order,pacemaker::constraint::colocation", "tripleo_ha_wrapper_puppet_debug": {"get_param": "ConfigDebug"}, "tripleo_ha_wrapper_config_suffix": ".previous_run"}}], "vars": {"tripleo_ha_wrapper_minor_update": true}}], "upgrade_tasks": [{"name": "redis_pacemaker_puppet_tmpfile_cleanup", "when": "step|int == 1", "block": [{"name": "Clean old tmpfile configuration", "file": {"path": "/etc/tmpfiles.d/var-run-redis.conf", "state": "absent"}}]}, {"name": "Tear-down non-HA redis container", "when": ["step|int == 0"], "block": [{"name": "Remove non-HA redis container", "include_role": {"name": "tripleo_container_rm"}, "vars": {"tripleo_container_cli": "{{ container_cli }}", "tripleo_containers_to_rm": ["redis"]}}]}, {"name": "Prepare switch of redis image name", "when": ["step|int == 0"], "block": [{"name": "Get redis image id currently used by pacemaker", "shell": "pcs resource config redis-bundle | grep -Eo 'image=[^ ]+' | awk -F= '{print $2;}'", "register": "redis_image_current_res", "failed_when": false}, {"name": "Image facts for redis", "set_fact": {"redis_image_latest": {"if": [{"get_param": "ClusterFullTag"}, "cluster.common.tag/redis:pcmklatest", {"yaql": {"data": {"if": [{"get_param": "ClusterCommonTag"}, {"yaql": {"data": {"get_attr": ["RoleParametersValue", "value", "ContainerRedisImage"]}, "expression": "concat(\"cluster.common.tag/\", $.data.rightSplit(separator => \"/\", maxSplits => 1)[1])"}}, {"get_attr": ["RoleParametersValue", "value", "ContainerRedisImage"]}]}, "expression": "concat($.data.rightSplit(separator => \":\", maxSplits => 1)[0], \":pcmklatest\")"}}]}, "redis_image_current": "{{redis_image_current_res.stdout}}"}}, {"name": "Temporarily tag the current redis image id with the upgraded image name", "import_role": {"name": "tripleo_container_tag"}, "vars": {"container_image": "{{redis_image_current}}", "container_image_latest": "{{redis_image_latest}}", "pull_image": false}, "when": ["redis_image_current != ''", "redis_image_current != redis_image_latest"]}, {"name": "Create redis retag statefile", "file": {"path": "/var/lib/tripleo/redis_needs_retag", "state": "touch"}, "when": ["redis_image_current != ''", "redis_image_current != redis_image_latest"]}]}, {"name": "Update redis-bundle pcs resource bundle for new container image", "when": ["step|int == 1"], "block": [{"name": "Set upgrade redis facts", "set_fact": {"is_redis_bootstrap_node": "{{redis_short_bootstrap_node_name|lower == ansible_facts['hostname']|lower}}"}}, {"name": "Check for redis retag statefile", "stat": {"path": "/var/lib/tripleo/redis_needs_retag"}, "register": "redis_retag_state_file"}]}, {"name": "Update redis-bundle pcs resource bundle for new container image", "when": ["step|int == 1", "is_redis_bootstrap_node|bool", "redis_retag_state_file.stat.exists|bool"], "block": [{"name": "Disable the redis cluster resource before container upgrade", "pacemaker_resource": {"resource": "redis-bundle", "state": "disable", "wait_for_resource": true}, "register": "output", "retries": 5, "until": "output.rc == 0"}, {"name": "Move redis logging to /var/log/containers", "block": [{"name": "Check redis logging configuration in pacemaker", "command": "cibadmin --query --xpath \"//storage-mapping[@id='redis-log' and @source-dir='/var/log/containers/redis']\"", "failed_when": false, "register": "redis_logs_moved"}, {"name": "Change redis logging configuration in pacemaker", "when": "redis_logs_moved.rc == 6", "block": [{"name": "Remove old bind mount for logging in the redis bundle", "command": "pcs resource bundle update redis-bundle storage-map remove redis-log"}, {"name": "Add a bind mount for logging in the redis bundle", "command": "pcs resource bundle update redis-bundle storage-map add id=redis-log source-dir=/var/log/containers/redis target-dir=/var/log/redis options=rw"}]}]}, {"name": "Update the redis bundle to use the new container image name", "command": "pcs resource bundle update redis-bundle container image={{redis_image_latest}}"}, {"name": "Enable the redis cluster resource", "pacemaker_resource": {"resource": "redis-bundle", "state": "enable", "wait_for_resource": true}, "register": "output", "retries": 5, "until": "output.rc == 0"}]}, {"name": "Check for redis retag statefile", "when": ["step|int == 3"], "stat": {"path": "/var/lib/tripleo/redis_needs_retag"}, "register": "redis_retag_state_file"}, {"name": "Retag redis-bundle container image", "when": ["step|int == 3", "redis_retag_state_file.stat.exists|bool"], "block": [{"name": "Disable the redis cluster resource before container upgrade", "pacemaker_resource": {"resource": "redis-bundle", "state": "disable", "wait_for_resource": true}, "register": "output", "retries": 5, "until": "output.rc == 0"}, {"name": "Retag the pacemaker image if containerized", "block": [{"block": [{"name": "Get redis image from pacemaker", "become": true, "register": "xmllint_pcmk_redis_image", "shell": "xmllint --xpath \"string(//bundle[@id='redis-bundle']/podman/@image)\" /var/lib/pacemaker/cib/cib.xml"}, {"name": "Get container redis image", "set_fact": {"redis_image": {"get_attr": ["RoleParametersValue", "value", "ContainerRedisImage"]}, "redis_image_latest": {"if": [{"get_param": "ClusterFullTag"}, "cluster.common.tag/redis:pcmklatest", {"yaql": {"data": {"if": [{"get_param": "ClusterCommonTag"}, {"yaql": {"data": {"get_attr": ["RoleParametersValue", "value", "ContainerRedisImage"]}, "expression": "concat(\"cluster.common.tag/\", $.data.rightSplit(separator => \"/\", maxSplits => 1)[1])"}}, {"get_attr": ["RoleParametersValue", "value", "ContainerRedisImage"]}]}, "expression": "concat($.data.rightSplit(separator => \":\", maxSplits => 1)[0], \":pcmklatest\")"}}]}, "pcmk_redis_image": "{{xmllint_pcmk_redis_image.stdout}}"}}]}, {"block": [{"name": "Retag pcmklatest to latest redis image", "include_role": {"name": "tripleo_container_tag"}, "vars": {"container_image": "{{redis_image}}", "container_image_latest": "{{redis_image_latest}}"}}]}]}, {"name": "Enable the redis-bundle cluster resource", "pacemaker_resource": {"resource": "redis-bundle", "state": "enable", "wait_for_resource": true}, "register": "output", "retries": 5, "until": "output.rc == 0"}, {"name": "Remove redis retag statefile", "file": {"path": "/var/lib/tripleo/redis_needs_retag", "state": "absent"}}]}]}}}}