From 0b80aca421a89b10a8254f03e1339d1ddfbd54f1 Mon Sep 17 00:00:00 2001
From: Russell Teague <rteague@redhat.com>
Date: Fri, 1 Dec 2017 09:24:45 -0500
Subject: Playbook Consolidation - Redeploy Certificates

---
 .../openshift-cluster/redeploy-certificates.yml    |  42 ---
 .../byo/openshift-cluster/redeploy-etcd-ca.yml     |   4 -
 .../redeploy-etcd-certificates.yml                 |  18 --
 .../redeploy-master-certificates.yml               |  10 -
 .../redeploy-node-certificates.yml                 |  10 -
 .../openshift-cluster/redeploy-openshift-ca.yml    |   4 -
 .../redeploy-registry-certificates.yml             |   4 -
 .../redeploy-router-certificates.yml               |   4 -
 .../redeploy-certificates/check-expiry.yml         |  12 -
 .../redeploy-certificates/etcd-backup.yml          |  19 --
 .../redeploy-certificates/etcd-ca.yml              | 101 -------
 .../redeploy-certificates/filter_plugins           |   1 -
 .../redeploy-certificates/library                  |   1 -
 .../redeploy-certificates/lookup_plugins           |   1 -
 .../redeploy-certificates/masters-backup.yml       |  38 ---
 .../redeploy-certificates/nodes-backup.yml         |  24 --
 .../redeploy-certificates/openshift-ca.yml         | 300 ---------------------
 .../redeploy-certificates/registry.yml             | 100 -------
 .../openshift-cluster/redeploy-certificates/roles  |   1 -
 .../redeploy-certificates/router.yml               | 141 ----------
 .../openshift-etcd/private/certificates-backup.yml |  19 ++
 playbooks/openshift-etcd/private/redeploy-ca.yml   | 101 +++++++
 .../private/redeploy-certificates.yml              |  18 ++
 playbooks/openshift-etcd/redeploy-ca.yml           |   4 +
 playbooks/openshift-etcd/redeploy-certificates.yml |  10 +
 .../private/redeploy-registry-certificates.yml     | 100 +++++++
 .../private/redeploy-router-certificates.yml       | 141 ++++++++++
 .../redeploy-registry-certificates.yml             |   4 +
 .../redeploy-router-certificates.yml               |   4 +
 .../private/certificates-backup.yml                |  38 +++
 .../private/redeploy-certificates.yml              |   6 +
 .../private/redeploy-openshift-ca.yml              | 300 +++++++++++++++++++++
 .../openshift-master/redeploy-certificates.yml     |   6 +
 .../openshift-master/redeploy-openshift-ca.yml     |   4 +
 .../openshift-node/private/certificates-backup.yml |  24 ++
 .../private/redeploy-certificates.yml              |   6 +
 playbooks/openshift-node/redeploy-certificates.yml |   6 +
 playbooks/redeploy-certificates.yml                |  26 ++
 38 files changed, 817 insertions(+), 835 deletions(-)
 delete mode 100644 playbooks/byo/openshift-cluster/redeploy-certificates.yml
 delete mode 100644 playbooks/byo/openshift-cluster/redeploy-etcd-ca.yml
 delete mode 100644 playbooks/byo/openshift-cluster/redeploy-etcd-certificates.yml
 delete mode 100644 playbooks/byo/openshift-cluster/redeploy-master-certificates.yml
 delete mode 100644 playbooks/byo/openshift-cluster/redeploy-node-certificates.yml
 delete mode 100644 playbooks/byo/openshift-cluster/redeploy-openshift-ca.yml
 delete mode 100644 playbooks/byo/openshift-cluster/redeploy-registry-certificates.yml
 delete mode 100644 playbooks/byo/openshift-cluster/redeploy-router-certificates.yml
 delete mode 100644 playbooks/common/openshift-cluster/redeploy-certificates/check-expiry.yml
 delete mode 100644 playbooks/common/openshift-cluster/redeploy-certificates/etcd-backup.yml
 delete mode 100644 playbooks/common/openshift-cluster/redeploy-certificates/etcd-ca.yml
 delete mode 120000 playbooks/common/openshift-cluster/redeploy-certificates/filter_plugins
 delete mode 120000 playbooks/common/openshift-cluster/redeploy-certificates/library
 delete mode 120000 playbooks/common/openshift-cluster/redeploy-certificates/lookup_plugins
 delete mode 100644 playbooks/common/openshift-cluster/redeploy-certificates/masters-backup.yml
 delete mode 100644 playbooks/common/openshift-cluster/redeploy-certificates/nodes-backup.yml
 delete mode 100644 playbooks/common/openshift-cluster/redeploy-certificates/openshift-ca.yml
 delete mode 100644 playbooks/common/openshift-cluster/redeploy-certificates/registry.yml
 delete mode 120000 playbooks/common/openshift-cluster/redeploy-certificates/roles
 delete mode 100644 playbooks/common/openshift-cluster/redeploy-certificates/router.yml
 create mode 100644 playbooks/openshift-etcd/private/certificates-backup.yml
 create mode 100644 playbooks/openshift-etcd/private/redeploy-ca.yml
 create mode 100644 playbooks/openshift-etcd/private/redeploy-certificates.yml
 create mode 100644 playbooks/openshift-etcd/redeploy-ca.yml
 create mode 100644 playbooks/openshift-etcd/redeploy-certificates.yml
 create mode 100644 playbooks/openshift-hosted/private/redeploy-registry-certificates.yml
 create mode 100644 playbooks/openshift-hosted/private/redeploy-router-certificates.yml
 create mode 100644 playbooks/openshift-hosted/redeploy-registry-certificates.yml
 create mode 100644 playbooks/openshift-hosted/redeploy-router-certificates.yml
 create mode 100644 playbooks/openshift-master/private/certificates-backup.yml
 create mode 100644 playbooks/openshift-master/private/redeploy-certificates.yml
 create mode 100644 playbooks/openshift-master/private/redeploy-openshift-ca.yml
 create mode 100644 playbooks/openshift-master/redeploy-certificates.yml
 create mode 100644 playbooks/openshift-master/redeploy-openshift-ca.yml
 create mode 100644 playbooks/openshift-node/private/certificates-backup.yml
 create mode 100644 playbooks/openshift-node/private/redeploy-certificates.yml
 create mode 100644 playbooks/openshift-node/redeploy-certificates.yml
 create mode 100644 playbooks/redeploy-certificates.yml

(limited to 'playbooks')

diff --git a/playbooks/byo/openshift-cluster/redeploy-certificates.yml b/playbooks/byo/openshift-cluster/redeploy-certificates.yml
deleted file mode 100644
index c26f11772..000000000
--- a/playbooks/byo/openshift-cluster/redeploy-certificates.yml
+++ /dev/null
@@ -1,42 +0,0 @@
----
-- include: ../../init/main.yml
-
-- include: ../../common/openshift-cluster/redeploy-certificates/check-expiry.yml
-  vars:
-    g_check_expiry_hosts: 'oo_etcd_to_config'
-
-- include: ../../common/openshift-cluster/redeploy-certificates/etcd-backup.yml
-
-- include: ../../openshift-etcd/private/certificates.yml
-  vars:
-    etcd_certificates_redeploy: true
-
-- include: ../../common/openshift-cluster/redeploy-certificates/masters-backup.yml
-
-- include: ../../openshift-master/private/certificates.yml
-  vars:
-    openshift_certificates_redeploy: true
-
-- include: ../../common/openshift-cluster/redeploy-certificates/nodes-backup.yml
-
-- include: ../../openshift-node/private/certificates.yml
-  vars:
-    openshift_certificates_redeploy: true
-
-- include: ../../openshift-etcd/private/restart.yml
-  vars:
-    g_etcd_certificates_expired: "{{ ('expired' in (hostvars | oo_select_keys(groups['etcd']) | oo_collect('check_results.check_results.etcd') | oo_collect('health'))) | bool }}"
-
-- include: ../../openshift-master/private/restart.yml
-
-- include: ../../openshift-node/private/restart.yml
-
-- include: ../../common/openshift-cluster/redeploy-certificates/router.yml
-  when: openshift_hosted_manage_router | default(true) | bool
-
-- include: ../../common/openshift-cluster/redeploy-certificates/registry.yml
-  when: openshift_hosted_manage_registry | default(true) | bool
-
-- include: ../../openshift-master/private/revert-client-ca.yml
-
-- include: ../../openshift-master/private/restart.yml
diff --git a/playbooks/byo/openshift-cluster/redeploy-etcd-ca.yml b/playbooks/byo/openshift-cluster/redeploy-etcd-ca.yml
deleted file mode 100644
index 77dd121b3..000000000
--- a/playbooks/byo/openshift-cluster/redeploy-etcd-ca.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-- include: ../../init/main.yml
-
-- include: ../../common/openshift-cluster/redeploy-certificates/etcd-ca.yml
diff --git a/playbooks/byo/openshift-cluster/redeploy-etcd-certificates.yml b/playbooks/byo/openshift-cluster/redeploy-etcd-certificates.yml
deleted file mode 100644
index 94e50cc28..000000000
--- a/playbooks/byo/openshift-cluster/redeploy-etcd-certificates.yml
+++ /dev/null
@@ -1,18 +0,0 @@
----
-- include: ../../init/main.yml
-
-- include: ../../common/openshift-cluster/redeploy-certificates/check-expiry.yml
-  vars:
-    g_check_expiry_hosts: 'oo_etcd_to_config'
-
-- include: ../../common/openshift-cluster/redeploy-certificates/etcd-backup.yml
-
-- include: ../../openshift-etcd/private/certificates.yml
-  vars:
-    etcd_certificates_redeploy: true
-
-- include: ../../openshift-etcd/private/restart.yml
-  vars:
-    g_etcd_certificates_expired: "{{ ('expired' in (hostvars | oo_select_keys(groups['etcd']) | oo_collect('check_results.check_results.etcd') | oo_collect('health'))) | bool }}"
-
-- include: ../../openshift-master/private/restart.yml
diff --git a/playbooks/byo/openshift-cluster/redeploy-master-certificates.yml b/playbooks/byo/openshift-cluster/redeploy-master-certificates.yml
deleted file mode 100644
index 88e52f809..000000000
--- a/playbooks/byo/openshift-cluster/redeploy-master-certificates.yml
+++ /dev/null
@@ -1,10 +0,0 @@
----
-- include: ../../init/main.yml
-
-- include: ../../common/openshift-cluster/redeploy-certificates/masters-backup.yml
-
-- include: ../../openshift-master/private/certificates.yml
-  vars:
-    openshift_certificates_redeploy: true
-
-- include: ../../openshift-master/private/restart.yml
diff --git a/playbooks/byo/openshift-cluster/redeploy-node-certificates.yml b/playbooks/byo/openshift-cluster/redeploy-node-certificates.yml
deleted file mode 100644
index 2abbe78f1..000000000
--- a/playbooks/byo/openshift-cluster/redeploy-node-certificates.yml
+++ /dev/null
@@ -1,10 +0,0 @@
----
-- include: ../../init/main.yml
-
-- include: ../../common/openshift-cluster/redeploy-certificates/nodes-backup.yml
-
-- include: ../../openshift-node/private/certificates.yml
-  vars:
-    openshift_certificates_redeploy: true
-
-- include: ../../openshift-node/private/restart.yml
diff --git a/playbooks/byo/openshift-cluster/redeploy-openshift-ca.yml b/playbooks/byo/openshift-cluster/redeploy-openshift-ca.yml
deleted file mode 100644
index 9cebeb1ee..000000000
--- a/playbooks/byo/openshift-cluster/redeploy-openshift-ca.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-- include: ../../init/main.yml
-
-- include: ../../common/openshift-cluster/redeploy-certificates/openshift-ca.yml
diff --git a/playbooks/byo/openshift-cluster/redeploy-registry-certificates.yml b/playbooks/byo/openshift-cluster/redeploy-registry-certificates.yml
deleted file mode 100644
index 36b6250a7..000000000
--- a/playbooks/byo/openshift-cluster/redeploy-registry-certificates.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-- include: ../../init/main.yml
-
-- include: ../../common/openshift-cluster/redeploy-certificates/registry.yml
diff --git a/playbooks/byo/openshift-cluster/redeploy-router-certificates.yml b/playbooks/byo/openshift-cluster/redeploy-router-certificates.yml
deleted file mode 100644
index 181e03381..000000000
--- a/playbooks/byo/openshift-cluster/redeploy-router-certificates.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-- include: ../../init/main.yml
-
-- include: ../../common/openshift-cluster/redeploy-certificates/router.yml
diff --git a/playbooks/common/openshift-cluster/redeploy-certificates/check-expiry.yml b/playbooks/common/openshift-cluster/redeploy-certificates/check-expiry.yml
deleted file mode 100644
index 4a9fbf7eb..000000000
--- a/playbooks/common/openshift-cluster/redeploy-certificates/check-expiry.yml
+++ /dev/null
@@ -1,12 +0,0 @@
----
-- name: Check cert expirys
-  hosts: "{{ g_check_expiry_hosts }}"
-  vars:
-    openshift_certificate_expiry_show_all: yes
-  roles:
-  # Sets 'check_results' per host which contains health status for
-  # etcd, master and node certificates.  We will use 'check_results'
-  # to determine if any certificates were expired prior to running
-  # this playbook. Service restarts will be skipped if any
-  # certificates were previously expired.
-  - role: openshift_certificate_expiry
diff --git a/playbooks/common/openshift-cluster/redeploy-certificates/etcd-backup.yml b/playbooks/common/openshift-cluster/redeploy-certificates/etcd-backup.yml
deleted file mode 100644
index d738c8207..000000000
--- a/playbooks/common/openshift-cluster/redeploy-certificates/etcd-backup.yml
+++ /dev/null
@@ -1,19 +0,0 @@
----
-- name: Backup and remove generated etcd certificates
-  hosts: oo_first_etcd
-  any_errors_fatal: true
-  tasks:
-  - include_role:
-      name: etcd
-      tasks_from: backup_generated_certificates
-  - include_role:
-      name: etcd
-      tasks_from: remove_generated_certificates
-
-- name: Backup deployed etcd certificates
-  hosts: oo_etcd_to_config
-  any_errors_fatal: true
-  tasks:
-  - include_role:
-      name: etcd
-      tasks_from: backup_server_certificates
diff --git a/playbooks/common/openshift-cluster/redeploy-certificates/etcd-ca.yml b/playbooks/common/openshift-cluster/redeploy-certificates/etcd-ca.yml
deleted file mode 100644
index 438f704bc..000000000
--- a/playbooks/common/openshift-cluster/redeploy-certificates/etcd-ca.yml
+++ /dev/null
@@ -1,101 +0,0 @@
----
-- name: Check cert expirys
-  hosts: oo_etcd_to_config:oo_masters_to_config
-  vars:
-    openshift_certificate_expiry_show_all: yes
-  roles:
-  # Sets 'check_results' per host which contains health status for
-  # etcd, master and node certificates.  We will use 'check_results'
-  # to determine if any certificates were expired prior to running
-  # this playbook. Service restarts will be skipped if any
-  # certificates were previously expired.
-  - role: openshift_certificate_expiry
-
-- name: Backup existing etcd CA certificate directories
-  hosts: oo_etcd_to_config
-  tasks:
-  - include_role:
-      name: etcd
-      tasks_from: backup_ca_certificates
-  - include_role:
-      name: etcd
-      tasks_from: remove_ca_certificates
-
-- include: ../../../openshift-etcd/private/ca.yml
-
-- name: Create temp directory for syncing certs
-  hosts: localhost
-  connection: local
-  become: no
-  gather_facts: no
-  tasks:
-  - name: Create local temp directory for syncing certs
-    local_action: command mktemp -d /tmp/openshift-ansible-XXXXXXX
-    register: g_etcd_mktemp
-    changed_when: false
-
-- name: Distribute etcd CA to etcd hosts
-  hosts: oo_etcd_to_config
-  tasks:
-  - include_role:
-      name: etcd
-      tasks_from: distribute_ca.yml
-    vars:
-      etcd_sync_cert_dir: "{{ hostvars['localhost'].g_etcd_mktemp.stdout }}"
-      etcd_ca_host: "{{ groups.oo_etcd_to_config.0 }}"
-
-- include: ../../../openshift-etcd/private/restart.yml
-  # Do not restart etcd when etcd certificates were previously expired.
-  when: ('expired' not in (hostvars
-                           | oo_select_keys(groups['etcd'])
-                           | oo_collect('check_results.check_results.etcd')
-                           | oo_collect('health')))
-
-- name: Retrieve etcd CA certificate
-  hosts: oo_first_etcd
-  tasks:
-  - include_role:
-      name: etcd
-      tasks_from: retrieve_ca_certificates
-    vars:
-      etcd_sync_cert_dir: "{{ hostvars['localhost'].g_etcd_mktemp.stdout }}"
-
-- name: Distribute etcd CA to masters
-  hosts: oo_masters_to_config
-  vars:
-    openshift_ca_host: "{{ groups.oo_first_master.0 }}"
-  tasks:
-  - name: Deploy etcd CA
-    copy:
-      src: "{{ hostvars['localhost'].g_etcd_mktemp.stdout }}/ca.crt"
-      dest: "{{ openshift.common.config_base }}/master/master.etcd-ca.crt"
-    when: groups.oo_etcd_to_config | default([]) | length > 0
-
-- name: Delete temporary directory on localhost
-  hosts: localhost
-  connection: local
-  become: no
-  gather_facts: no
-  tasks:
-  - file:
-      name: "{{ g_etcd_mktemp.stdout }}"
-      state: absent
-    changed_when: false
-
-- include: ../../../openshift-master/private/restart.yml
-  # Do not restart masters when master or etcd certificates were previously expired.
-  when:
-  # masters
-  - ('expired' not in hostvars
-      | oo_select_keys(groups['oo_masters_to_config'])
-      | oo_collect('check_results.check_results.ocp_certs')
-      | oo_collect('health', {'path':hostvars[groups.oo_first_master.0].openshift.common.config_base ~ "/master/master.server.crt"}))
-  - ('expired' not in hostvars
-      | oo_select_keys(groups['oo_masters_to_config'])
-      | oo_collect('check_results.check_results.ocp_certs')
-      | oo_collect('health', {'path':hostvars[groups.oo_first_master.0].openshift.common.config_base ~ "/master/ca-bundle.crt"}))
-  # etcd
-  - ('expired' not in (hostvars
-      | oo_select_keys(groups['etcd'])
-      | oo_collect('check_results.check_results.etcd')
-      | oo_collect('health')))
diff --git a/playbooks/common/openshift-cluster/redeploy-certificates/filter_plugins b/playbooks/common/openshift-cluster/redeploy-certificates/filter_plugins
deleted file mode 120000
index b1213dedb..000000000
--- a/playbooks/common/openshift-cluster/redeploy-certificates/filter_plugins
+++ /dev/null
@@ -1 +0,0 @@
-../../../../filter_plugins
\ No newline at end of file
diff --git a/playbooks/common/openshift-cluster/redeploy-certificates/library b/playbooks/common/openshift-cluster/redeploy-certificates/library
deleted file mode 120000
index 9a53f009d..000000000
--- a/playbooks/common/openshift-cluster/redeploy-certificates/library
+++ /dev/null
@@ -1 +0,0 @@
-../../../../library
\ No newline at end of file
diff --git a/playbooks/common/openshift-cluster/redeploy-certificates/lookup_plugins b/playbooks/common/openshift-cluster/redeploy-certificates/lookup_plugins
deleted file mode 120000
index aff753026..000000000
--- a/playbooks/common/openshift-cluster/redeploy-certificates/lookup_plugins
+++ /dev/null
@@ -1 +0,0 @@
-../../../../lookup_plugins
\ No newline at end of file
diff --git a/playbooks/common/openshift-cluster/redeploy-certificates/masters-backup.yml b/playbooks/common/openshift-cluster/redeploy-certificates/masters-backup.yml
deleted file mode 100644
index 4dbc041b0..000000000
--- a/playbooks/common/openshift-cluster/redeploy-certificates/masters-backup.yml
+++ /dev/null
@@ -1,38 +0,0 @@
----
-- name: Backup and remove master cerftificates
-  hosts: oo_masters_to_config
-  any_errors_fatal: true
-  vars:
-    openshift_ca_host: "{{ groups.oo_first_master.0 }}"
-    openshift_master_count: "{{ openshift.master.master_count | default(groups.oo_masters | length) }}"
-  pre_tasks:
-  - stat:
-      path: "{{ openshift.common.config_base }}/generated-configs"
-    register: openshift_generated_configs_dir_stat
-  - name: Backup generated certificate and config directories
-    command: >
-      tar -czvf /etc/origin/master-node-cert-config-backup-{{ ansible_date_time.epoch }}.tgz
-      {{ openshift.common.config_base }}/generated-configs
-      {{ openshift.common.config_base }}/master
-    when: openshift_generated_configs_dir_stat.stat.exists
-    delegate_to: "{{ openshift_ca_host }}"
-    run_once: true
-  - name: Remove generated certificate directories
-    file:
-      path: "{{ item }}"
-      state: absent
-    with_items:
-    - "{{ openshift.common.config_base }}/generated-configs"
-  - name: Remove generated certificates
-    file:
-      path: "{{ openshift.common.config_base }}/master/{{ item }}"
-      state: absent
-    with_items:
-    - "{{ hostvars[inventory_hostname] | certificates_to_synchronize(include_keys=false, include_ca=false) }}"
-    - "etcd.server.crt"
-    - "etcd.server.key"
-    - "master.server.crt"
-    - "master.server.key"
-    - "openshift-master.crt"
-    - "openshift-master.key"
-    - "openshift-master.kubeconfig"
diff --git a/playbooks/common/openshift-cluster/redeploy-certificates/nodes-backup.yml b/playbooks/common/openshift-cluster/redeploy-certificates/nodes-backup.yml
deleted file mode 100644
index 2ad84b3b9..000000000
--- a/playbooks/common/openshift-cluster/redeploy-certificates/nodes-backup.yml
+++ /dev/null
@@ -1,24 +0,0 @@
----
-- name: Ensure node directory is absent from generated configs
-  hosts: oo_first_master
-  tasks:
-  # The generated configs directory (/etc/origin/generated-configs) is
-  # backed up during redeployment of the control plane certificates.
-  # We need to ensure that the generated config directory for
-  # individual nodes has been deleted before continuing, so verify
-  # that it is missing here.
-  - name: Ensure node directories and tarballs are absent from generated configs
-    shell: >
-      rm -rf {{ openshift.common.config_base }}/generated-configs/node-*
-    args:
-      warn: no
-
-- name: Redeploy node certificates
-  hosts: oo_nodes_to_config
-  pre_tasks:
-  - name: Remove CA certificate
-    file:
-      path: "{{ item }}"
-      state: absent
-    with_items:
-    - "{{ openshift.common.config_base }}/node/ca.crt"
diff --git a/playbooks/common/openshift-cluster/redeploy-certificates/openshift-ca.yml b/playbooks/common/openshift-cluster/redeploy-certificates/openshift-ca.yml
deleted file mode 100644
index 5a837d80d..000000000
--- a/playbooks/common/openshift-cluster/redeploy-certificates/openshift-ca.yml
+++ /dev/null
@@ -1,300 +0,0 @@
----
-- name: Check cert expirys
-  hosts: oo_nodes_to_config:oo_masters_to_config:oo_etcd_to_config
-  vars:
-    openshift_certificate_expiry_show_all: yes
-  roles:
-  # Sets 'check_results' per host which contains health status for
-  # etcd, master and node certificates.  We will use 'check_results'
-  # to determine if any certificates were expired prior to running
-  # this playbook. Service restarts will be skipped if any
-  # certificates were previously expired.
-  - role: openshift_certificate_expiry
-
-# Update master config when ca-bundle not referenced. Services will be
-# restarted below after new CA certificate has been distributed.
-- name: Ensure ca-bundle.crt is referenced in master configuration
-  hosts: oo_masters_to_config
-  tasks:
-  - slurp:
-      src: "{{ openshift.common.config_base }}/master/master-config.yaml"
-    register: g_master_config_output
-  - modify_yaml:
-      dest: "{{ openshift.common.config_base }}/master/master-config.yaml"
-      yaml_key: kubeletClientInfo.ca
-      yaml_value: ca-bundle.crt
-    when: (g_master_config_output.content|b64decode|from_yaml).kubeletClientInfo.ca != 'ca-bundle.crt'
-  - modify_yaml:
-      dest: "{{ openshift.common.config_base }}/master/master-config.yaml"
-      yaml_key: serviceAccountConfig.masterCA
-      yaml_value: ca-bundle.crt
-    when: (g_master_config_output.content|b64decode|from_yaml).serviceAccountConfig.masterCA != 'ca-bundle.crt'
-  - modify_yaml:
-      dest: "{{ openshift.common.config_base }}/master/master-config.yaml"
-      yaml_key: oauthConfig.masterCA
-      yaml_value: ca-bundle.crt
-    when: (g_master_config_output.content|b64decode|from_yaml).oauthConfig.masterCA != 'ca-bundle.crt'
-  - modify_yaml:
-      dest: "{{ openshift.common.config_base }}/master/master-config.yaml"
-      yaml_key: etcdClientInfo.ca
-      yaml_value: ca-bundle.crt
-    when:
-    - groups.oo_etcd_to_config | default([]) | length == 0
-    - (g_master_config_output.content|b64decode|from_yaml).etcdClientInfo.ca != 'ca-bundle.crt'
-  - modify_yaml:
-      dest: "{{ openshift.common.config_base }}/master/master-config.yaml"
-      yaml_key: etcdConfig.peerServingInfo.clientCA
-      yaml_value: ca-bundle.crt
-    when:
-    - groups.oo_etcd_to_config | default([]) | length == 0
-    - (g_master_config_output.content|b64decode|from_yaml).etcdConfig.peerServingInfo.clientCA != 'ca-bundle.crt'
-  - modify_yaml:
-      dest: "{{ openshift.common.config_base }}/master/master-config.yaml"
-      yaml_key: etcdConfig.servingInfo.clientCA
-      yaml_value: ca-bundle.crt
-    when:
-    - groups.oo_etcd_to_config | default([]) | length == 0
-    - (g_master_config_output.content|b64decode|from_yaml).etcdConfig.servingInfo.clientCA != 'ca-bundle.crt'
-  # Set servingInfo.clientCA to client-ca-bundle.crt in order to roll the CA certificate.
-  # This change will be reverted in playbooks/byo/openshift-cluster/redeploy-certificates.yml
-  - modify_yaml:
-      dest: "{{ openshift.common.config_base }}/master/master-config.yaml"
-      yaml_key: servingInfo.clientCA
-      yaml_value: client-ca-bundle.crt
-    when: (g_master_config_output.content|b64decode|from_yaml).servingInfo.clientCA != 'client-ca-bundle.crt'
-
-- name: Copy current OpenShift CA to legacy directory
-  hosts: oo_masters_to_config
-  pre_tasks:
-  - name: Create legacy-ca directory
-    file:
-      path: "{{ openshift.common.config_base }}/master/legacy-ca"
-      state: directory
-      mode: 0700
-      owner: root
-      group: root
-  - command: mktemp -u XXXXXX
-    register: g_legacy_ca_mktemp
-    changed_when: false
-  # Copy CA certificate, key, serial and bundle to legacy-ca with a
-  # prefix generated by mktemp, ie. XXXXXX-ca.crt.
-  #
-  # The following roles will pick up all CA certificates matching
-  # /.*-ca.crt/ in the legacy-ca directory and ensure they are present
-  # in the OpenShift CA bundle.
-  # - openshift_ca
-  # - openshift_master_certificates
-  # - openshift_node_certificates
-  - name: Copy current OpenShift CA to legacy directory
-    copy:
-      src: "{{ openshift.common.config_base }}/master/{{ item }}"
-      dest: "{{ openshift.common.config_base }}/master/legacy-ca/{{ g_legacy_ca_mktemp.stdout }}-{{ item }}"
-      remote_src: true
-    # It is possible that redeploying failed and files may be missing.
-    # Ignore errors in this case. Files should have been copied to
-    # legacy-ca directory in previous run.
-    ignore_errors: true
-    with_items:
-    - "ca.crt"
-    - "ca.key"
-    - "ca.serial.txt"
-    - "ca-bundle.crt"
-
-- name: Create temporary directory for creating new CA certificate
-  hosts: oo_first_master
-  tasks:
-  - name: Create temporary directory for creating new CA certificate
-    command: >
-      mktemp -d /tmp/openshift-ansible-XXXXXXX
-    register: g_new_openshift_ca_mktemp
-    changed_when: false
-
-- name: Create OpenShift CA
-  hosts: oo_first_master
-  vars:
-    # Set openshift_ca_config_dir to a temporary directory where CA
-    # will be created. We'll replace the existing CA with the CA
-    # created in the temporary directory.
-    openshift_ca_config_dir: "{{ hostvars[groups.oo_first_master.0].g_new_openshift_ca_mktemp.stdout }}"
-  roles:
-  - role: openshift_master_facts
-  - role: openshift_named_certificates
-  - role: openshift_ca
-    openshift_ca_host: "{{ groups.oo_first_master.0 }}"
-
-- name: Create temp directory for syncing certs
-  hosts: localhost
-  connection: local
-  become: no
-  gather_facts: no
-  tasks:
-  - name: Create local temp directory for syncing certs
-    local_action: command mktemp -d /tmp/openshift-ansible-XXXXXXX
-    register: g_master_mktemp
-    changed_when: false
-
-- name: Retrieve OpenShift CA
-  hosts: oo_first_master
-  vars:
-    openshift_ca_host: "{{ groups.oo_first_master.0 }}"
-  tasks:
-  - name: Retrieve CA certificate, key, bundle and serial
-    fetch:
-      src: "{{ hostvars[openshift_ca_host].g_new_openshift_ca_mktemp.stdout }}/{{ item }}"
-      dest: "{{ hostvars['localhost'].g_master_mktemp.stdout }}/"
-      flat: yes
-      fail_on_missing: yes
-      validate_checksum: yes
-    with_items:
-    - ca.crt
-    - ca.key
-    - ca-bundle.crt
-    - ca.serial.txt
-    - client-ca-bundle.crt
-    delegate_to: "{{ openshift_ca_host }}"
-    run_once: true
-    changed_when: false
-
-- name: Distribute OpenShift CA to masters
-  hosts: oo_masters_to_config
-  vars:
-    openshift_ca_host: "{{ groups.oo_first_master.0 }}"
-  tasks:
-  - name: Deploy CA certificate, key, bundle and serial
-    copy:
-      src: "{{ hostvars['localhost'].g_master_mktemp.stdout }}/{{ item }}"
-      dest: "{{ openshift.common.config_base }}/master/"
-    with_items:
-    - ca.crt
-    - ca.key
-    - ca-bundle.crt
-    - ca.serial.txt
-    - client-ca-bundle.crt
-  - name: Update master client kubeconfig CA data
-    kubeclient_ca:
-      client_path: "{{ openshift.common.config_base }}/master/openshift-master.kubeconfig"
-      ca_path: "{{ openshift.common.config_base }}/master/ca-bundle.crt"
-  - name: Update admin client kubeconfig CA data
-    kubeclient_ca:
-      client_path: "{{ openshift.common.config_base }}/master/admin.kubeconfig"
-      ca_path: "{{ openshift.common.config_base }}/master/ca-bundle.crt"
-  - name: Lookup default group for ansible_ssh_user
-    command: "/usr/bin/id -g {{ ansible_ssh_user | quote }}"
-    changed_when: false
-    register: _ansible_ssh_user_gid
-  - set_fact:
-      client_users: "{{ [ansible_ssh_user, 'root'] | unique }}"
-  - name: Create the client config dir(s)
-    file:
-      path: "~{{ item }}/.kube"
-      state: directory
-      mode: 0700
-      owner: "{{ item }}"
-      group: "{{ 'root' if item == 'root' else _ansible_ssh_user_gid.stdout  }}"
-    with_items: "{{ client_users }}"
-  - name: Copy the admin client config(s)
-    copy:
-      src: "{{ openshift.common.config_base }}/master/admin.kubeconfig"
-      dest: "~{{ item }}/.kube/config"
-      remote_src: yes
-    with_items: "{{ client_users }}"
-  - name: Update the permissions on the admin client config(s)
-    file:
-      path: "~{{ item }}/.kube/config"
-      state: file
-      mode: 0700
-      owner: "{{ item }}"
-      group: "{{ 'root' if item == 'root' else _ansible_ssh_user_gid.stdout  }}"
-    with_items: "{{ client_users }}"
-
-- include: ../../../openshift-master/private/restart.yml
-  # Do not restart masters when master or etcd certificates were previously expired.
-  when:
-  # masters
-  - ('expired' not in hostvars
-      | oo_select_keys(groups['oo_masters_to_config'])
-      | oo_collect('check_results.check_results.ocp_certs')
-      | oo_collect('health', {'path':hostvars[groups.oo_first_master.0].openshift.common.config_base ~ "/master/master.server.crt"}))
-  - ('expired' not in hostvars
-      | oo_select_keys(groups['oo_masters_to_config'])
-      | oo_collect('check_results.check_results.ocp_certs')
-      | oo_collect('health', {'path':hostvars[groups.oo_first_master.0].openshift.common.config_base ~ "/master/ca-bundle.crt"}))
-  # etcd
-  - ('expired' not in (hostvars
-      | oo_select_keys(groups['etcd'])
-      | oo_collect('check_results.check_results.etcd')
-      | oo_collect('health')))
-
-- name: Distribute OpenShift CA certificate to nodes
-  hosts: oo_nodes_to_config
-  vars:
-    openshift_ca_host: "{{ groups.oo_first_master.0 }}"
-  tasks:
-  - copy:
-      src: "{{ hostvars['localhost'].g_master_mktemp.stdout }}/ca-bundle.crt"
-      dest: "{{ openshift.common.config_base }}/node/ca.crt"
-  - name: Copy OpenShift CA to system CA trust
-    copy:
-      src: "{{ item.cert }}"
-      dest: "/etc/pki/ca-trust/source/anchors/{{ item.id }}-{{ item.cert | basename }}"
-      remote_src: yes
-    with_items:
-    - id: openshift
-      cert: "{{ openshift.common.config_base }}/node/ca.crt"
-    notify:
-    - update ca trust
-  - name: Update node client kubeconfig CA data
-    kubeclient_ca:
-      client_path: "{{ openshift.common.config_base }}/node/system:node:{{ openshift.common.hostname }}.kubeconfig"
-      ca_path: "{{ openshift.common.config_base }}/node/ca.crt"
-  handlers:
-  # Normally this handler would restart docker after updating ca
-  # trust. We'll do that when we restart nodes to avoid restarting
-  # docker on all nodes in parallel.
-  - name: update ca trust
-    command: update-ca-trust
-
-- name: Delete temporary directory on CA host
-  hosts: oo_first_master
-  tasks:
-  - file:
-      path: "{{ g_new_openshift_ca_mktemp.stdout }}"
-      state: absent
-
-- name: Delete temporary directory on localhost
-  hosts: localhost
-  connection: local
-  become: no
-  gather_facts: no
-  tasks:
-  - file:
-      name: "{{ g_master_mktemp.stdout }}"
-      state: absent
-    changed_when: false
-
-- include: ../../../openshift-node/private/restart.yml
-  # Do not restart nodes when node, master or etcd certificates were previously expired.
-  when:
-  # nodes
-  - ('expired' not in hostvars
-      | oo_select_keys(groups['oo_nodes_to_config'])
-      | oo_collect('check_results.check_results.ocp_certs')
-      | oo_collect('health', {'path':hostvars[groups.oo_nodes_to_config.0].openshift.common.config_base ~ "/node/server.crt"}))
-  - ('expired' not in hostvars
-      | oo_select_keys(groups['oo_nodes_to_config'])
-      | oo_collect('check_results.check_results.ocp_certs')
-      | oo_collect('health', {'path':hostvars[groups.oo_nodes_to_config.0].openshift.common.config_base ~ "/node/ca.crt"}))
-  # masters
-  - ('expired' not in hostvars
-      | oo_select_keys(groups['oo_masters_to_config'])
-      | oo_collect('check_results.check_results.ocp_certs')
-      | oo_collect('health', {'path':hostvars[groups.oo_first_master.0].openshift.common.config_base ~ "/master/master.server.crt"}))
-  - ('expired' not in hostvars
-      | oo_select_keys(groups['oo_masters_to_config'])
-      | oo_collect('check_results.check_results.ocp_certs')
-      | oo_collect('health', {'path':hostvars[groups.oo_first_master.0].openshift.common.config_base ~ "/master/ca-bundle.crt"}))
-  # etcd
-  - ('expired' not in (hostvars
-      | oo_select_keys(groups['etcd'])
-      | oo_collect('check_results.check_results.etcd')
-      | oo_collect('health')))
diff --git a/playbooks/common/openshift-cluster/redeploy-certificates/registry.yml b/playbooks/common/openshift-cluster/redeploy-certificates/registry.yml
deleted file mode 100644
index 7e9363c5f..000000000
--- a/playbooks/common/openshift-cluster/redeploy-certificates/registry.yml
+++ /dev/null
@@ -1,100 +0,0 @@
----
-- name: Update registry certificates
-  hosts: oo_first_master
-  vars:
-  roles:
-  - lib_openshift
-  tasks:
-  - name: Create temp directory for kubeconfig
-    command: mktemp -d /tmp/openshift-ansible-XXXXXX
-    register: mktemp
-    changed_when: false
-
-  - name: Copy admin client config(s)
-    command: >
-      cp {{ openshift.common.config_base }}/master//admin.kubeconfig {{ mktemp.stdout }}/admin.kubeconfig
-    changed_when: false
-
-  - name: Determine if docker-registry exists
-    command: >
-      {{ openshift.common.client_binary }} get dc/docker-registry -o json
-      --config={{ mktemp.stdout }}/admin.kubeconfig
-      -n default
-    register: l_docker_registry_dc
-    failed_when: false
-    changed_when: false
-
-  - set_fact:
-      docker_registry_env_vars: "{{ ((l_docker_registry_dc.stdout | from_json)['spec']['template']['spec']['containers'][0]['env']
-                                      | oo_collect('name'))
-                                      | default([]) }}"
-      docker_registry_secrets: "{{ ((l_docker_registry_dc.stdout | from_json)['spec']['template']['spec']['volumes']
-                                     | oo_collect('secret')
-                                     | oo_collect('secretName'))
-                                     | default([]) }}"
-    changed_when: false
-    when: l_docker_registry_dc.rc == 0
-
-  # Replace dc/docker-registry environment variable certificate data if set.
-  - name: Update docker-registry environment variables
-    shell: >
-      {{ openshift.common.client_binary }} env dc/docker-registry
-      OPENSHIFT_CA_DATA="$(cat /etc/origin/master/ca.crt)"
-      OPENSHIFT_CERT_DATA="$(cat /etc/origin/master/openshift-registry.crt)"
-      OPENSHIFT_KEY_DATA="$(cat /etc/origin/master/openshift-registry.key)"
-      --config={{ mktemp.stdout }}/admin.kubeconfig
-      -n default
-    when: l_docker_registry_dc.rc == 0 and 'OPENSHIFT_CA_DATA' in docker_registry_env_vars and 'OPENSHIFT_CERT_DATA' in docker_registry_env_vars and 'OPENSHIFT_KEY_DATA' in docker_registry_env_vars
-
-  # Replace dc/docker-registry certificate secret contents if set.
-  - block:
-    - name: Retrieve registry service IP
-      oc_service:
-        namespace: default
-        name: docker-registry
-        state: list
-      register: docker_registry_service_ip
-      changed_when: false
-
-    - set_fact:
-        docker_registry_route_hostname: "{{ 'docker-registry-default.' ~ (openshift.master.default_subdomain | default('router.default.svc.cluster.local', true)) }}"
-      changed_when: false
-
-    - name: Generate registry certificate
-      command: >
-        {{ openshift.common.client_binary }} adm ca create-server-cert
-        --signer-cert={{ openshift.common.config_base }}/master/ca.crt
-        --signer-key={{ openshift.common.config_base }}/master/ca.key
-        --signer-serial={{ openshift.common.config_base }}/master/ca.serial.txt
-        --config={{ mktemp.stdout }}/admin.kubeconfig
-        --hostnames="{{ docker_registry_service_ip.results.clusterip }},docker-registry.default.svc,docker-registry.default.svc.cluster.local,{{ docker_registry_route_hostname }}"
-        --cert={{ openshift.common.config_base }}/master/registry.crt
-        --key={{ openshift.common.config_base }}/master/registry.key
-        --expire-days={{ openshift_hosted_registry_cert_expire_days | default(730) }}
-
-    - name: Update registry certificates secret
-      oc_secret:
-        kubeconfig: "{{ mktemp.stdout }}/admin.kubeconfig"
-        name: registry-certificates
-        namespace: default
-        state: present
-        files:
-        - name: registry.crt
-          path: "{{ openshift.common.config_base }}/master/registry.crt"
-        - name: registry.key
-          path: "{{ openshift.common.config_base }}/master/registry.key"
-      run_once: true
-    when: l_docker_registry_dc.rc == 0 and 'registry-certificates' in docker_registry_secrets and 'REGISTRY_HTTP_TLS_CERTIFICATE' in docker_registry_env_vars and 'REGISTRY_HTTP_TLS_KEY' in docker_registry_env_vars
-
-  - name: Redeploy docker registry
-    command: >
-      {{ openshift.common.client_binary }} deploy dc/docker-registry
-      --latest
-      --config={{ mktemp.stdout }}/admin.kubeconfig
-      -n default
-
-  - name: Delete temp directory
-    file:
-      name: "{{ mktemp.stdout }}"
-      state: absent
-    changed_when: False
diff --git a/playbooks/common/openshift-cluster/redeploy-certificates/roles b/playbooks/common/openshift-cluster/redeploy-certificates/roles
deleted file mode 120000
index 4bdbcbad3..000000000
--- a/playbooks/common/openshift-cluster/redeploy-certificates/roles
+++ /dev/null
@@ -1 +0,0 @@
-../../../../roles
\ No newline at end of file
diff --git a/playbooks/common/openshift-cluster/redeploy-certificates/router.yml b/playbooks/common/openshift-cluster/redeploy-certificates/router.yml
deleted file mode 100644
index 2116c745c..000000000
--- a/playbooks/common/openshift-cluster/redeploy-certificates/router.yml
+++ /dev/null
@@ -1,141 +0,0 @@
----
-- name: Update router certificates
-  hosts: oo_first_master
-  vars:
-  roles:
-  - lib_openshift
-  tasks:
-  - name: Create temp directory for kubeconfig
-    command: mktemp -d /tmp/openshift-ansible-XXXXXX
-    register: router_cert_redeploy_tempdir
-    changed_when: false
-
-  - name: Copy admin client config(s)
-    command: >
-      cp {{ openshift.common.config_base }}/master//admin.kubeconfig {{ router_cert_redeploy_tempdir.stdout }}/admin.kubeconfig
-    changed_when: false
-
-  - name: Determine if router exists
-    command: >
-      {{ openshift.common.client_binary }} get dc/router -o json
-      --config={{ router_cert_redeploy_tempdir.stdout }}/admin.kubeconfig
-      -n default
-    register: l_router_dc
-    failed_when: false
-    changed_when: false
-
-  - name: Determine if router service exists
-    command: >
-      {{ openshift.common.client_binary }} get svc/router -o json
-      --config={{ router_cert_redeploy_tempdir.stdout }}/admin.kubeconfig
-      -n default
-    register: l_router_svc
-    failed_when: false
-    changed_when: false
-
-  - name: Collect router environment variables and secrets
-    set_fact:
-      router_env_vars: "{{ ((l_router_dc.stdout | from_json)['spec']['template']['spec']['containers'][0]['env']
-                             | oo_collect('name'))
-                             | default([]) }}"
-      router_secrets: "{{ ((l_router_dc.stdout | from_json)['spec']['template']['spec']['volumes']
-                            | oo_collect('secret')
-                            | oo_collect('secretName'))
-                            | default([]) }}"
-    changed_when: false
-    when: l_router_dc.rc == 0
-
-  - name: Collect router service annotations
-    set_fact:
-      router_service_annotations: "{{ (l_router_svc.stdout | from_json)['metadata']['annotations'] if 'annotations' in (l_router_svc.stdout | from_json)['metadata'] else [] }}"
-    when: l_router_svc.rc == 0
-
-  - name: Update router environment variables
-    shell: >
-      {{ openshift.common.client_binary }} env dc/router
-      OPENSHIFT_CA_DATA="$(cat /etc/origin/master/ca.crt)"
-      OPENSHIFT_CERT_DATA="$(cat /etc/origin/master/openshift-router.crt)"
-      OPENSHIFT_KEY_DATA="$(cat /etc/origin/master/openshift-router.key)"
-      --config={{ router_cert_redeploy_tempdir.stdout }}/admin.kubeconfig
-      -n default
-    when:
-    - l_router_dc.rc == 0
-    - ('OPENSHIFT_CA_DATA' in router_env_vars)
-    - ('OPENSHIFT_CERT_DATA' in router_env_vars)
-    - ('OPENSHIFT_KEY_DATA' in router_env_vars)
-
-  # When the router service contains service signer annotations we
-  # will delete the existing certificate secret and allow OpenShift to
-  # replace the secret.
-  - block:
-    - name: Delete existing router certificate secret
-      oc_secret:
-        kubeconfig: "{{ router_cert_redeploy_tempdir.stdout }}/admin.kubeconfig"
-        name: router-certs
-        namespace: default
-        state: absent
-      run_once: true
-
-    - name: Remove router service annotations
-      command: >
-        {{ openshift.common.client_binary }} annotate service/router
-        service.alpha.openshift.io/serving-cert-secret-name-
-        service.alpha.openshift.io/serving-cert-signed-by-
-        --config={{ router_cert_redeploy_tempdir.stdout }}/admin.kubeconfig
-        -n default
-
-    - name: Add serving-cert-secret annotation to router service
-      command: >
-        {{ openshift.common.client_binary }} annotate service/router
-        service.alpha.openshift.io/serving-cert-secret-name=router-certs
-        --config={{ router_cert_redeploy_tempdir.stdout }}/admin.kubeconfig
-        -n default
-    when:
-    - l_router_dc.rc == 0
-    - l_router_svc.rc == 0
-    - ('router-certs' in router_secrets)
-    - openshift_hosted_router_certificate is undefined
-    - ('service.alpha.openshift.io/serving-cert-secret-name') in router_service_annotations
-    - ('service.alpha.openshift.io/serving-cert-signed-by') in router_service_annotations
-
-  # When there are no annotations on the router service we will allow
-  # the openshift_hosted role to either create a new wildcard
-  # certificate (since we deleted the original) or reapply a custom
-  # openshift_hosted_router_certificate.
-  - file:
-      path: "{{ item }}"
-      state: absent
-    with_items:
-    - /etc/origin/master/openshift-router.crt
-    - /etc/origin/master/openshift-router.key
-    when:
-    - l_router_dc.rc == 0
-    - l_router_svc.rc == 0
-    - ('router-certs' in router_secrets)
-    - ('service.alpha.openshift.io/serving-cert-secret-name') not in router_service_annotations
-    - ('service.alpha.openshift.io/serving-cert-signed-by') not in router_service_annotations
-
-  - include_role:
-      name: openshift_hosted
-      tasks_from: main
-    vars:
-      openshift_hosted_manage_registry: false
-    when:
-    - l_router_dc.rc == 0
-    - l_router_svc.rc == 0
-    - ('router-certs' in router_secrets)
-    - ('service.alpha.openshift.io/serving-cert-secret-name') not in router_service_annotations
-    - ('service.alpha.openshift.io/serving-cert-signed-by') not in router_service_annotations
-
-  - name: Redeploy router
-    command: >
-      {{ openshift.common.client_binary }} deploy dc/router
-      --latest
-      --config={{ router_cert_redeploy_tempdir.stdout }}/admin.kubeconfig
-      -n default
-
-  - name: Delete temp directory
-    file:
-      name: "{{ router_cert_redeploy_tempdir.stdout }}"
-      state: absent
-    changed_when: False
diff --git a/playbooks/openshift-etcd/private/certificates-backup.yml b/playbooks/openshift-etcd/private/certificates-backup.yml
new file mode 100644
index 000000000..d738c8207
--- /dev/null
+++ b/playbooks/openshift-etcd/private/certificates-backup.yml
@@ -0,0 +1,19 @@
+---
+- name: Backup and remove generated etcd certificates
+  hosts: oo_first_etcd
+  any_errors_fatal: true
+  tasks:
+  - include_role:
+      name: etcd
+      tasks_from: backup_generated_certificates
+  - include_role:
+      name: etcd
+      tasks_from: remove_generated_certificates
+
+- name: Backup deployed etcd certificates
+  hosts: oo_etcd_to_config
+  any_errors_fatal: true
+  tasks:
+  - include_role:
+      name: etcd
+      tasks_from: backup_server_certificates
diff --git a/playbooks/openshift-etcd/private/redeploy-ca.yml b/playbooks/openshift-etcd/private/redeploy-ca.yml
new file mode 100644
index 000000000..cc5d57031
--- /dev/null
+++ b/playbooks/openshift-etcd/private/redeploy-ca.yml
@@ -0,0 +1,101 @@
+---
+- name: Check cert expirys
+  hosts: oo_etcd_to_config:oo_masters_to_config
+  vars:
+    openshift_certificate_expiry_show_all: yes
+  roles:
+  # Sets 'check_results' per host which contains health status for
+  # etcd, master and node certificates.  We will use 'check_results'
+  # to determine if any certificates were expired prior to running
+  # this playbook. Service restarts will be skipped if any
+  # certificates were previously expired.
+  - role: openshift_certificate_expiry
+
+- name: Backup existing etcd CA certificate directories
+  hosts: oo_etcd_to_config
+  tasks:
+  - include_role:
+      name: etcd
+      tasks_from: backup_ca_certificates
+  - include_role:
+      name: etcd
+      tasks_from: remove_ca_certificates
+
+- include: ca.yml
+
+- name: Create temp directory for syncing certs
+  hosts: localhost
+  connection: local
+  become: no
+  gather_facts: no
+  tasks:
+  - name: Create local temp directory for syncing certs
+    local_action: command mktemp -d /tmp/openshift-ansible-XXXXXXX
+    register: g_etcd_mktemp
+    changed_when: false
+
+- name: Distribute etcd CA to etcd hosts
+  hosts: oo_etcd_to_config
+  tasks:
+  - include_role:
+      name: etcd
+      tasks_from: distribute_ca.yml
+    vars:
+      etcd_sync_cert_dir: "{{ hostvars['localhost'].g_etcd_mktemp.stdout }}"
+      etcd_ca_host: "{{ groups.oo_etcd_to_config.0 }}"
+
+- include: restart.yml
+  # Do not restart etcd when etcd certificates were previously expired.
+  when: ('expired' not in (hostvars
+                           | oo_select_keys(groups['etcd'])
+                           | oo_collect('check_results.check_results.etcd')
+                           | oo_collect('health')))
+
+- name: Retrieve etcd CA certificate
+  hosts: oo_first_etcd
+  tasks:
+  - include_role:
+      name: etcd
+      tasks_from: retrieve_ca_certificates
+    vars:
+      etcd_sync_cert_dir: "{{ hostvars['localhost'].g_etcd_mktemp.stdout }}"
+
+- name: Distribute etcd CA to masters
+  hosts: oo_masters_to_config
+  vars:
+    openshift_ca_host: "{{ groups.oo_first_master.0 }}"
+  tasks:
+  - name: Deploy etcd CA
+    copy:
+      src: "{{ hostvars['localhost'].g_etcd_mktemp.stdout }}/ca.crt"
+      dest: "{{ openshift.common.config_base }}/master/master.etcd-ca.crt"
+    when: groups.oo_etcd_to_config | default([]) | length > 0
+
+- name: Delete temporary directory on localhost
+  hosts: localhost
+  connection: local
+  become: no
+  gather_facts: no
+  tasks:
+  - file:
+      name: "{{ g_etcd_mktemp.stdout }}"
+      state: absent
+    changed_when: false
+
+- include: ../../openshift-master/private/restart.yml
+  # Do not restart masters when master or etcd certificates were previously expired.
+  when:
+  # masters
+  - ('expired' not in hostvars
+      | oo_select_keys(groups['oo_masters_to_config'])
+      | oo_collect('check_results.check_results.ocp_certs')
+      | oo_collect('health', {'path':hostvars[groups.oo_first_master.0].openshift.common.config_base ~ "/master/master.server.crt"}))
+  - ('expired' not in hostvars
+      | oo_select_keys(groups['oo_masters_to_config'])
+      | oo_collect('check_results.check_results.ocp_certs')
+      | oo_collect('health', {'path':hostvars[groups.oo_first_master.0].openshift.common.config_base ~ "/master/ca-bundle.crt"}))
+  # etcd
+  - ('expired' not in (hostvars
+      | oo_select_keys(groups['etcd'])
+      | oo_collect('check_results.check_results.etcd')
+      | oo_collect('health')))
diff --git a/playbooks/openshift-etcd/private/redeploy-certificates.yml b/playbooks/openshift-etcd/private/redeploy-certificates.yml
new file mode 100644
index 000000000..cc1e6adf5
--- /dev/null
+++ b/playbooks/openshift-etcd/private/redeploy-certificates.yml
@@ -0,0 +1,18 @@
+---
+- name: Check cert expirys
+  hosts: oo_etcd_to_config
+  vars:
+    openshift_certificate_expiry_show_all: yes
+  roles:
+  # Sets 'check_results' per host which contains health status for
+  # etcd, master and node certificates.  We will use 'check_results'
+  # to determine if any certificates were expired prior to running
+  # this playbook. Service restarts will be skipped if any
+  # certificates were previously expired.
+  - role: openshift_certificate_expiry
+
+- include: certificates-backup.yml
+
+- include: certificates.yml
+  vars:
+    etcd_certificates_redeploy: true
diff --git a/playbooks/openshift-etcd/redeploy-ca.yml b/playbooks/openshift-etcd/redeploy-ca.yml
new file mode 100644
index 000000000..b1d23675d
--- /dev/null
+++ b/playbooks/openshift-etcd/redeploy-ca.yml
@@ -0,0 +1,4 @@
+---
+- include: ../init/main.yml
+
+- include: private/redeploy-ca.yml
diff --git a/playbooks/openshift-etcd/redeploy-certificates.yml b/playbooks/openshift-etcd/redeploy-certificates.yml
new file mode 100644
index 000000000..1bd302c03
--- /dev/null
+++ b/playbooks/openshift-etcd/redeploy-certificates.yml
@@ -0,0 +1,10 @@
+---
+- include: ../init/main.yml
+
+- include: private/redeploy-certificates.yml
+
+- include: private/restart.yml
+  vars:
+    g_etcd_certificates_expired: "{{ ('expired' in (hostvars | oo_select_keys(groups['etcd']) | oo_collect('check_results.check_results.etcd') | oo_collect('health'))) | bool }}"
+
+- include: ../openshift-master/private/restart.yml
diff --git a/playbooks/openshift-hosted/private/redeploy-registry-certificates.yml b/playbooks/openshift-hosted/private/redeploy-registry-certificates.yml
new file mode 100644
index 000000000..7e9363c5f
--- /dev/null
+++ b/playbooks/openshift-hosted/private/redeploy-registry-certificates.yml
@@ -0,0 +1,100 @@
+---
+- name: Update registry certificates
+  hosts: oo_first_master
+  vars:
+  roles:
+  - lib_openshift
+  tasks:
+  - name: Create temp directory for kubeconfig
+    command: mktemp -d /tmp/openshift-ansible-XXXXXX
+    register: mktemp
+    changed_when: false
+
+  - name: Copy admin client config(s)
+    command: >
+      cp {{ openshift.common.config_base }}/master//admin.kubeconfig {{ mktemp.stdout }}/admin.kubeconfig
+    changed_when: false
+
+  - name: Determine if docker-registry exists
+    command: >
+      {{ openshift.common.client_binary }} get dc/docker-registry -o json
+      --config={{ mktemp.stdout }}/admin.kubeconfig
+      -n default
+    register: l_docker_registry_dc
+    failed_when: false
+    changed_when: false
+
+  - set_fact:
+      docker_registry_env_vars: "{{ ((l_docker_registry_dc.stdout | from_json)['spec']['template']['spec']['containers'][0]['env']
+                                      | oo_collect('name'))
+                                      | default([]) }}"
+      docker_registry_secrets: "{{ ((l_docker_registry_dc.stdout | from_json)['spec']['template']['spec']['volumes']
+                                     | oo_collect('secret')
+                                     | oo_collect('secretName'))
+                                     | default([]) }}"
+    changed_when: false
+    when: l_docker_registry_dc.rc == 0
+
+  # Replace dc/docker-registry environment variable certificate data if set.
+  - name: Update docker-registry environment variables
+    shell: >
+      {{ openshift.common.client_binary }} env dc/docker-registry
+      OPENSHIFT_CA_DATA="$(cat /etc/origin/master/ca.crt)"
+      OPENSHIFT_CERT_DATA="$(cat /etc/origin/master/openshift-registry.crt)"
+      OPENSHIFT_KEY_DATA="$(cat /etc/origin/master/openshift-registry.key)"
+      --config={{ mktemp.stdout }}/admin.kubeconfig
+      -n default
+    when: l_docker_registry_dc.rc == 0 and 'OPENSHIFT_CA_DATA' in docker_registry_env_vars and 'OPENSHIFT_CERT_DATA' in docker_registry_env_vars and 'OPENSHIFT_KEY_DATA' in docker_registry_env_vars
+
+  # Replace dc/docker-registry certificate secret contents if set.
+  - block:
+    - name: Retrieve registry service IP
+      oc_service:
+        namespace: default
+        name: docker-registry
+        state: list
+      register: docker_registry_service_ip
+      changed_when: false
+
+    - set_fact:
+        docker_registry_route_hostname: "{{ 'docker-registry-default.' ~ (openshift.master.default_subdomain | default('router.default.svc.cluster.local', true)) }}"
+      changed_when: false
+
+    - name: Generate registry certificate
+      command: >
+        {{ openshift.common.client_binary }} adm ca create-server-cert
+        --signer-cert={{ openshift.common.config_base }}/master/ca.crt
+        --signer-key={{ openshift.common.config_base }}/master/ca.key
+        --signer-serial={{ openshift.common.config_base }}/master/ca.serial.txt
+        --config={{ mktemp.stdout }}/admin.kubeconfig
+        --hostnames="{{ docker_registry_service_ip.results.clusterip }},docker-registry.default.svc,docker-registry.default.svc.cluster.local,{{ docker_registry_route_hostname }}"
+        --cert={{ openshift.common.config_base }}/master/registry.crt
+        --key={{ openshift.common.config_base }}/master/registry.key
+        --expire-days={{ openshift_hosted_registry_cert_expire_days | default(730) }}
+
+    - name: Update registry certificates secret
+      oc_secret:
+        kubeconfig: "{{ mktemp.stdout }}/admin.kubeconfig"
+        name: registry-certificates
+        namespace: default
+        state: present
+        files:
+        - name: registry.crt
+          path: "{{ openshift.common.config_base }}/master/registry.crt"
+        - name: registry.key
+          path: "{{ openshift.common.config_base }}/master/registry.key"
+      run_once: true
+    when: l_docker_registry_dc.rc == 0 and 'registry-certificates' in docker_registry_secrets and 'REGISTRY_HTTP_TLS_CERTIFICATE' in docker_registry_env_vars and 'REGISTRY_HTTP_TLS_KEY' in docker_registry_env_vars
+
+  - name: Redeploy docker registry
+    command: >
+      {{ openshift.common.client_binary }} deploy dc/docker-registry
+      --latest
+      --config={{ mktemp.stdout }}/admin.kubeconfig
+      -n default
+
+  - name: Delete temp directory
+    file:
+      name: "{{ mktemp.stdout }}"
+      state: absent
+    changed_when: False
diff --git a/playbooks/openshift-hosted/private/redeploy-router-certificates.yml b/playbooks/openshift-hosted/private/redeploy-router-certificates.yml
new file mode 100644
index 000000000..2116c745c
--- /dev/null
+++ b/playbooks/openshift-hosted/private/redeploy-router-certificates.yml
@@ -0,0 +1,141 @@
+---
+- name: Update router certificates
+  hosts: oo_first_master
+  vars:
+  roles:
+  - lib_openshift
+  tasks:
+  - name: Create temp directory for kubeconfig
+    command: mktemp -d /tmp/openshift-ansible-XXXXXX
+    register: router_cert_redeploy_tempdir
+    changed_when: false
+
+  - name: Copy admin client config(s)
+    command: >
+      cp {{ openshift.common.config_base }}/master//admin.kubeconfig {{ router_cert_redeploy_tempdir.stdout }}/admin.kubeconfig
+    changed_when: false
+
+  - name: Determine if router exists
+    command: >
+      {{ openshift.common.client_binary }} get dc/router -o json
+      --config={{ router_cert_redeploy_tempdir.stdout }}/admin.kubeconfig
+      -n default
+    register: l_router_dc
+    failed_when: false
+    changed_when: false
+
+  - name: Determine if router service exists
+    command: >
+      {{ openshift.common.client_binary }} get svc/router -o json
+      --config={{ router_cert_redeploy_tempdir.stdout }}/admin.kubeconfig
+      -n default
+    register: l_router_svc
+    failed_when: false
+    changed_when: false
+
+  - name: Collect router environment variables and secrets
+    set_fact:
+      router_env_vars: "{{ ((l_router_dc.stdout | from_json)['spec']['template']['spec']['containers'][0]['env']
+                             | oo_collect('name'))
+                             | default([]) }}"
+      router_secrets: "{{ ((l_router_dc.stdout | from_json)['spec']['template']['spec']['volumes']
+                            | oo_collect('secret')
+                            | oo_collect('secretName'))
+                            | default([]) }}"
+    changed_when: false
+    when: l_router_dc.rc == 0
+
+  - name: Collect router service annotations
+    set_fact:
+      router_service_annotations: "{{ (l_router_svc.stdout | from_json)['metadata']['annotations'] if 'annotations' in (l_router_svc.stdout | from_json)['metadata'] else [] }}"
+    when: l_router_svc.rc == 0
+
+  - name: Update router environment variables
+    shell: >
+      {{ openshift.common.client_binary }} env dc/router
+      OPENSHIFT_CA_DATA="$(cat /etc/origin/master/ca.crt)"
+      OPENSHIFT_CERT_DATA="$(cat /etc/origin/master/openshift-router.crt)"
+      OPENSHIFT_KEY_DATA="$(cat /etc/origin/master/openshift-router.key)"
+      --config={{ router_cert_redeploy_tempdir.stdout }}/admin.kubeconfig
+      -n default
+    when:
+    - l_router_dc.rc == 0
+    - ('OPENSHIFT_CA_DATA' in router_env_vars)
+    - ('OPENSHIFT_CERT_DATA' in router_env_vars)
+    - ('OPENSHIFT_KEY_DATA' in router_env_vars)
+
+  # When the router service contains service signer annotations we
+  # will delete the existing certificate secret and allow OpenShift to
+  # replace the secret.
+  - block:
+    - name: Delete existing router certificate secret
+      oc_secret:
+        kubeconfig: "{{ router_cert_redeploy_tempdir.stdout }}/admin.kubeconfig"
+        name: router-certs
+        namespace: default
+        state: absent
+      run_once: true
+
+    - name: Remove router service annotations
+      command: >
+        {{ openshift.common.client_binary }} annotate service/router
+        service.alpha.openshift.io/serving-cert-secret-name-
+        service.alpha.openshift.io/serving-cert-signed-by-
+        --config={{ router_cert_redeploy_tempdir.stdout }}/admin.kubeconfig
+        -n default
+
+    - name: Add serving-cert-secret annotation to router service
+      command: >
+        {{ openshift.common.client_binary }} annotate service/router
+        service.alpha.openshift.io/serving-cert-secret-name=router-certs
+        --config={{ router_cert_redeploy_tempdir.stdout }}/admin.kubeconfig
+        -n default
+    when:
+    - l_router_dc.rc == 0
+    - l_router_svc.rc == 0
+    - ('router-certs' in router_secrets)
+    - openshift_hosted_router_certificate is undefined
+    - ('service.alpha.openshift.io/serving-cert-secret-name') in router_service_annotations
+    - ('service.alpha.openshift.io/serving-cert-signed-by') in router_service_annotations
+
+  # When there are no annotations on the router service we will allow
+  # the openshift_hosted role to either create a new wildcard
+  # certificate (since we deleted the original) or reapply a custom
+  # openshift_hosted_router_certificate.
+  - file:
+      path: "{{ item }}"
+      state: absent
+    with_items:
+    - /etc/origin/master/openshift-router.crt
+    - /etc/origin/master/openshift-router.key
+    when:
+    - l_router_dc.rc == 0
+    - l_router_svc.rc == 0
+    - ('router-certs' in router_secrets)
+    - ('service.alpha.openshift.io/serving-cert-secret-name') not in router_service_annotations
+    - ('service.alpha.openshift.io/serving-cert-signed-by') not in router_service_annotations
+
+  - include_role:
+      name: openshift_hosted
+      tasks_from: main
+    vars:
+      openshift_hosted_manage_registry: false
+    when:
+    - l_router_dc.rc == 0
+    - l_router_svc.rc == 0
+    - ('router-certs' in router_secrets)
+    - ('service.alpha.openshift.io/serving-cert-secret-name') not in router_service_annotations
+    - ('service.alpha.openshift.io/serving-cert-signed-by') not in router_service_annotations
+
+  - name: Redeploy router
+    command: >
+      {{ openshift.common.client_binary }} deploy dc/router
+      --latest
+      --config={{ router_cert_redeploy_tempdir.stdout }}/admin.kubeconfig
+      -n default
+
+  - name: Delete temp directory
+    file:
+      name: "{{ router_cert_redeploy_tempdir.stdout }}"
+      state: absent
+    changed_when: False
diff --git a/playbooks/openshift-hosted/redeploy-registry-certificates.yml b/playbooks/openshift-hosted/redeploy-registry-certificates.yml
new file mode 100644
index 000000000..65fb0abda
--- /dev/null
+++ b/playbooks/openshift-hosted/redeploy-registry-certificates.yml
@@ -0,0 +1,4 @@
+---
+- include: ../init/main.yml
+
+- include: private/redeploy-registry-certificates.yml
diff --git a/playbooks/openshift-hosted/redeploy-router-certificates.yml b/playbooks/openshift-hosted/redeploy-router-certificates.yml
new file mode 100644
index 000000000..8dc052751
--- /dev/null
+++ b/playbooks/openshift-hosted/redeploy-router-certificates.yml
@@ -0,0 +1,4 @@
+---
+- include: ../init/main.yml
+
+- include: private/redeploy-router-certificates.yml
diff --git a/playbooks/openshift-master/private/certificates-backup.yml b/playbooks/openshift-master/private/certificates-backup.yml
new file mode 100644
index 000000000..4dbc041b0
--- /dev/null
+++ b/playbooks/openshift-master/private/certificates-backup.yml
@@ -0,0 +1,38 @@
+---
+- name: Backup and remove master cerftificates
+  hosts: oo_masters_to_config
+  any_errors_fatal: true
+  vars:
+    openshift_ca_host: "{{ groups.oo_first_master.0 }}"
+    openshift_master_count: "{{ openshift.master.master_count | default(groups.oo_masters | length) }}"
+  pre_tasks:
+  - stat:
+      path: "{{ openshift.common.config_base }}/generated-configs"
+    register: openshift_generated_configs_dir_stat
+  - name: Backup generated certificate and config directories
+    command: >
+      tar -czvf /etc/origin/master-node-cert-config-backup-{{ ansible_date_time.epoch }}.tgz
+      {{ openshift.common.config_base }}/generated-configs
+      {{ openshift.common.config_base }}/master
+    when: openshift_generated_configs_dir_stat.stat.exists
+    delegate_to: "{{ openshift_ca_host }}"
+    run_once: true
+  - name: Remove generated certificate directories
+    file:
+      path: "{{ item }}"
+      state: absent
+    with_items:
+    - "{{ openshift.common.config_base }}/generated-configs"
+  - name: Remove generated certificates
+    file:
+      path: "{{ openshift.common.config_base }}/master/{{ item }}"
+      state: absent
+    with_items:
+    - "{{ hostvars[inventory_hostname] | certificates_to_synchronize(include_keys=false, include_ca=false) }}"
+    - "etcd.server.crt"
+    - "etcd.server.key"
+    - "master.server.crt"
+    - "master.server.key"
+    - "openshift-master.crt"
+    - "openshift-master.key"
+    - "openshift-master.kubeconfig"
diff --git a/playbooks/openshift-master/private/redeploy-certificates.yml b/playbooks/openshift-master/private/redeploy-certificates.yml
new file mode 100644
index 000000000..3bd38a61d
--- /dev/null
+++ b/playbooks/openshift-master/private/redeploy-certificates.yml
@@ -0,0 +1,6 @@
+---
+- include: certificates-backup.yml
+
+- include: certificates.yml
+  vars:
+    openshift_certificates_redeploy: true
diff --git a/playbooks/openshift-master/private/redeploy-openshift-ca.yml b/playbooks/openshift-master/private/redeploy-openshift-ca.yml
new file mode 100644
index 000000000..59657574a
--- /dev/null
+++ b/playbooks/openshift-master/private/redeploy-openshift-ca.yml
@@ -0,0 +1,300 @@
+---
+- name: Check cert expirys
+  hosts: oo_nodes_to_config:oo_masters_to_config:oo_etcd_to_config
+  vars:
+    openshift_certificate_expiry_show_all: yes
+  roles:
+  # Sets 'check_results' per host which contains health status for
+  # etcd, master and node certificates.  We will use 'check_results'
+  # to determine if any certificates were expired prior to running
+  # this playbook. Service restarts will be skipped if any
+  # certificates were previously expired.
+  - role: openshift_certificate_expiry
+
+# Update master config when ca-bundle not referenced. Services will be
+# restarted below after new CA certificate has been distributed.
+- name: Ensure ca-bundle.crt is referenced in master configuration
+  hosts: oo_masters_to_config
+  tasks:
+  - slurp:
+      src: "{{ openshift.common.config_base }}/master/master-config.yaml"
+    register: g_master_config_output
+  - modify_yaml:
+      dest: "{{ openshift.common.config_base }}/master/master-config.yaml"
+      yaml_key: kubeletClientInfo.ca
+      yaml_value: ca-bundle.crt
+    when: (g_master_config_output.content|b64decode|from_yaml).kubeletClientInfo.ca != 'ca-bundle.crt'
+  - modify_yaml:
+      dest: "{{ openshift.common.config_base }}/master/master-config.yaml"
+      yaml_key: serviceAccountConfig.masterCA
+      yaml_value: ca-bundle.crt
+    when: (g_master_config_output.content|b64decode|from_yaml).serviceAccountConfig.masterCA != 'ca-bundle.crt'
+  - modify_yaml:
+      dest: "{{ openshift.common.config_base }}/master/master-config.yaml"
+      yaml_key: oauthConfig.masterCA
+      yaml_value: ca-bundle.crt
+    when: (g_master_config_output.content|b64decode|from_yaml).oauthConfig.masterCA != 'ca-bundle.crt'
+  - modify_yaml:
+      dest: "{{ openshift.common.config_base }}/master/master-config.yaml"
+      yaml_key: etcdClientInfo.ca
+      yaml_value: ca-bundle.crt
+    when:
+    - groups.oo_etcd_to_config | default([]) | length == 0
+    - (g_master_config_output.content|b64decode|from_yaml).etcdClientInfo.ca != 'ca-bundle.crt'
+  - modify_yaml:
+      dest: "{{ openshift.common.config_base }}/master/master-config.yaml"
+      yaml_key: etcdConfig.peerServingInfo.clientCA
+      yaml_value: ca-bundle.crt
+    when:
+    - groups.oo_etcd_to_config | default([]) | length == 0
+    - (g_master_config_output.content|b64decode|from_yaml).etcdConfig.peerServingInfo.clientCA != 'ca-bundle.crt'
+  - modify_yaml:
+      dest: "{{ openshift.common.config_base }}/master/master-config.yaml"
+      yaml_key: etcdConfig.servingInfo.clientCA
+      yaml_value: ca-bundle.crt
+    when:
+    - groups.oo_etcd_to_config | default([]) | length == 0
+    - (g_master_config_output.content|b64decode|from_yaml).etcdConfig.servingInfo.clientCA != 'ca-bundle.crt'
+  # Set servingInfo.clientCA to client-ca-bundle.crt in order to roll the CA certificate.
+  # This change will be reverted in playbooks/byo/openshift-cluster/redeploy-certificates.yml
+  - modify_yaml:
+      dest: "{{ openshift.common.config_base }}/master/master-config.yaml"
+      yaml_key: servingInfo.clientCA
+      yaml_value: client-ca-bundle.crt
+    when: (g_master_config_output.content|b64decode|from_yaml).servingInfo.clientCA != 'client-ca-bundle.crt'
+
+- name: Copy current OpenShift CA to legacy directory
+  hosts: oo_masters_to_config
+  pre_tasks:
+  - name: Create legacy-ca directory
+    file:
+      path: "{{ openshift.common.config_base }}/master/legacy-ca"
+      state: directory
+      mode: 0700
+      owner: root
+      group: root
+  - command: mktemp -u XXXXXX
+    register: g_legacy_ca_mktemp
+    changed_when: false
+  # Copy CA certificate, key, serial and bundle to legacy-ca with a
+  # prefix generated by mktemp, ie. XXXXXX-ca.crt.
+  #
+  # The following roles will pick up all CA certificates matching
+  # /.*-ca.crt/ in the legacy-ca directory and ensure they are present
+  # in the OpenShift CA bundle.
+  # - openshift_ca
+  # - openshift_master_certificates
+  # - openshift_node_certificates
+  - name: Copy current OpenShift CA to legacy directory
+    copy:
+      src: "{{ openshift.common.config_base }}/master/{{ item }}"
+      dest: "{{ openshift.common.config_base }}/master/legacy-ca/{{ g_legacy_ca_mktemp.stdout }}-{{ item }}"
+      remote_src: true
+    # It is possible that redeploying failed and files may be missing.
+    # Ignore errors in this case. Files should have been copied to
+    # legacy-ca directory in previous run.
+    ignore_errors: true
+    with_items:
+    - "ca.crt"
+    - "ca.key"
+    - "ca.serial.txt"
+    - "ca-bundle.crt"
+
+- name: Create temporary directory for creating new CA certificate
+  hosts: oo_first_master
+  tasks:
+  - name: Create temporary directory for creating new CA certificate
+    command: >
+      mktemp -d /tmp/openshift-ansible-XXXXXXX
+    register: g_new_openshift_ca_mktemp
+    changed_when: false
+
+- name: Create OpenShift CA
+  hosts: oo_first_master
+  vars:
+    # Set openshift_ca_config_dir to a temporary directory where CA
+    # will be created. We'll replace the existing CA with the CA
+    # created in the temporary directory.
+    openshift_ca_config_dir: "{{ hostvars[groups.oo_first_master.0].g_new_openshift_ca_mktemp.stdout }}"
+  roles:
+  - role: openshift_master_facts
+  - role: openshift_named_certificates
+  - role: openshift_ca
+    openshift_ca_host: "{{ groups.oo_first_master.0 }}"
+
+- name: Create temp directory for syncing certs
+  hosts: localhost
+  connection: local
+  become: no
+  gather_facts: no
+  tasks:
+  - name: Create local temp directory for syncing certs
+    local_action: command mktemp -d /tmp/openshift-ansible-XXXXXXX
+    register: g_master_mktemp
+    changed_when: false
+
+- name: Retrieve OpenShift CA
+  hosts: oo_first_master
+  vars:
+    openshift_ca_host: "{{ groups.oo_first_master.0 }}"
+  tasks:
+  - name: Retrieve CA certificate, key, bundle and serial
+    fetch:
+      src: "{{ hostvars[openshift_ca_host].g_new_openshift_ca_mktemp.stdout }}/{{ item }}"
+      dest: "{{ hostvars['localhost'].g_master_mktemp.stdout }}/"
+      flat: yes
+      fail_on_missing: yes
+      validate_checksum: yes
+    with_items:
+    - ca.crt
+    - ca.key
+    - ca-bundle.crt
+    - ca.serial.txt
+    - client-ca-bundle.crt
+    delegate_to: "{{ openshift_ca_host }}"
+    run_once: true
+    changed_when: false
+
+- name: Distribute OpenShift CA to masters
+  hosts: oo_masters_to_config
+  vars:
+    openshift_ca_host: "{{ groups.oo_first_master.0 }}"
+  tasks:
+  - name: Deploy CA certificate, key, bundle and serial
+    copy:
+      src: "{{ hostvars['localhost'].g_master_mktemp.stdout }}/{{ item }}"
+      dest: "{{ openshift.common.config_base }}/master/"
+    with_items:
+    - ca.crt
+    - ca.key
+    - ca-bundle.crt
+    - ca.serial.txt
+    - client-ca-bundle.crt
+  - name: Update master client kubeconfig CA data
+    kubeclient_ca:
+      client_path: "{{ openshift.common.config_base }}/master/openshift-master.kubeconfig"
+      ca_path: "{{ openshift.common.config_base }}/master/ca-bundle.crt"
+  - name: Update admin client kubeconfig CA data
+    kubeclient_ca:
+      client_path: "{{ openshift.common.config_base }}/master/admin.kubeconfig"
+      ca_path: "{{ openshift.common.config_base }}/master/ca-bundle.crt"
+  - name: Lookup default group for ansible_ssh_user
+    command: "/usr/bin/id -g {{ ansible_ssh_user | quote }}"
+    changed_when: false
+    register: _ansible_ssh_user_gid
+  - set_fact:
+      client_users: "{{ [ansible_ssh_user, 'root'] | unique }}"
+  - name: Create the client config dir(s)
+    file:
+      path: "~{{ item }}/.kube"
+      state: directory
+      mode: 0700
+      owner: "{{ item }}"
+      group: "{{ 'root' if item == 'root' else _ansible_ssh_user_gid.stdout  }}"
+    with_items: "{{ client_users }}"
+  - name: Copy the admin client config(s)
+    copy:
+      src: "{{ openshift.common.config_base }}/master/admin.kubeconfig"
+      dest: "~{{ item }}/.kube/config"
+      remote_src: yes
+    with_items: "{{ client_users }}"
+  - name: Update the permissions on the admin client config(s)
+    file:
+      path: "~{{ item }}/.kube/config"
+      state: file
+      mode: 0700
+      owner: "{{ item }}"
+      group: "{{ 'root' if item == 'root' else _ansible_ssh_user_gid.stdout  }}"
+    with_items: "{{ client_users }}"
+
+- include: restart.yml
+  # Do not restart masters when master or etcd certificates were previously expired.
+  when:
+  # masters
+  - ('expired' not in hostvars
+      | oo_select_keys(groups['oo_masters_to_config'])
+      | oo_collect('check_results.check_results.ocp_certs')
+      | oo_collect('health', {'path':hostvars[groups.oo_first_master.0].openshift.common.config_base ~ "/master/master.server.crt"}))
+  - ('expired' not in hostvars
+      | oo_select_keys(groups['oo_masters_to_config'])
+      | oo_collect('check_results.check_results.ocp_certs')
+      | oo_collect('health', {'path':hostvars[groups.oo_first_master.0].openshift.common.config_base ~ "/master/ca-bundle.crt"}))
+  # etcd
+  - ('expired' not in (hostvars
+      | oo_select_keys(groups['etcd'])
+      | oo_collect('check_results.check_results.etcd')
+      | oo_collect('health')))
+
+- name: Distribute OpenShift CA certificate to nodes
+  hosts: oo_nodes_to_config
+  vars:
+    openshift_ca_host: "{{ groups.oo_first_master.0 }}"
+  tasks:
+  - copy:
+      src: "{{ hostvars['localhost'].g_master_mktemp.stdout }}/ca-bundle.crt"
+      dest: "{{ openshift.common.config_base }}/node/ca.crt"
+  - name: Copy OpenShift CA to system CA trust
+    copy:
+      src: "{{ item.cert }}"
+      dest: "/etc/pki/ca-trust/source/anchors/{{ item.id }}-{{ item.cert | basename }}"
+      remote_src: yes
+    with_items:
+    - id: openshift
+      cert: "{{ openshift.common.config_base }}/node/ca.crt"
+    notify:
+    - update ca trust
+  - name: Update node client kubeconfig CA data
+    kubeclient_ca:
+      client_path: "{{ openshift.common.config_base }}/node/system:node:{{ openshift.common.hostname }}.kubeconfig"
+      ca_path: "{{ openshift.common.config_base }}/node/ca.crt"
+  handlers:
+  # Normally this handler would restart docker after updating ca
+  # trust. We'll do that when we restart nodes to avoid restarting
+  # docker on all nodes in parallel.
+  - name: update ca trust
+    command: update-ca-trust
+
+- name: Delete temporary directory on CA host
+  hosts: oo_first_master
+  tasks:
+  - file:
+      path: "{{ g_new_openshift_ca_mktemp.stdout }}"
+      state: absent
+
+- name: Delete temporary directory on localhost
+  hosts: localhost
+  connection: local
+  become: no
+  gather_facts: no
+  tasks:
+  - file:
+      name: "{{ g_master_mktemp.stdout }}"
+      state: absent
+    changed_when: false
+
+- include: ../../openshift-node/private/restart.yml
+  # Do not restart nodes when node, master or etcd certificates were previously expired.
+  when:
+  # nodes
+  - ('expired' not in hostvars
+      | oo_select_keys(groups['oo_nodes_to_config'])
+      | oo_collect('check_results.check_results.ocp_certs')
+      | oo_collect('health', {'path':hostvars[groups.oo_nodes_to_config.0].openshift.common.config_base ~ "/node/server.crt"}))
+  - ('expired' not in hostvars
+      | oo_select_keys(groups['oo_nodes_to_config'])
+      | oo_collect('check_results.check_results.ocp_certs')
+      | oo_collect('health', {'path':hostvars[groups.oo_nodes_to_config.0].openshift.common.config_base ~ "/node/ca.crt"}))
+  # masters
+  - ('expired' not in hostvars
+      | oo_select_keys(groups['oo_masters_to_config'])
+      | oo_collect('check_results.check_results.ocp_certs')
+      | oo_collect('health', {'path':hostvars[groups.oo_first_master.0].openshift.common.config_base ~ "/master/master.server.crt"}))
+  - ('expired' not in hostvars
+      | oo_select_keys(groups['oo_masters_to_config'])
+      | oo_collect('check_results.check_results.ocp_certs')
+      | oo_collect('health', {'path':hostvars[groups.oo_first_master.0].openshift.common.config_base ~ "/master/ca-bundle.crt"}))
+  # etcd
+  - ('expired' not in (hostvars
+      | oo_select_keys(groups['etcd'])
+      | oo_collect('check_results.check_results.etcd')
+      | oo_collect('health')))
diff --git a/playbooks/openshift-master/redeploy-certificates.yml b/playbooks/openshift-master/redeploy-certificates.yml
new file mode 100644
index 000000000..df727247b
--- /dev/null
+++ b/playbooks/openshift-master/redeploy-certificates.yml
@@ -0,0 +1,6 @@
+---
+- include: ../init/main.yml
+
+- include: private/redeploy-certificates.yml
+
+- include: private/restart.yml
diff --git a/playbooks/openshift-master/redeploy-openshift-ca.yml b/playbooks/openshift-master/redeploy-openshift-ca.yml
new file mode 100644
index 000000000..3ae74c7a0
--- /dev/null
+++ b/playbooks/openshift-master/redeploy-openshift-ca.yml
@@ -0,0 +1,4 @@
+---
+- include: ../init/main.yml
+
+- include: private/redeploy-openshift-ca.yml
diff --git a/playbooks/openshift-node/private/certificates-backup.yml b/playbooks/openshift-node/private/certificates-backup.yml
new file mode 100644
index 000000000..2ad84b3b9
--- /dev/null
+++ b/playbooks/openshift-node/private/certificates-backup.yml
@@ -0,0 +1,24 @@
+---
+- name: Ensure node directory is absent from generated configs
+  hosts: oo_first_master
+  tasks:
+  # The generated configs directory (/etc/origin/generated-configs) is
+  # backed up during redeployment of the control plane certificates.
+  # We need to ensure that the generated config directory for
+  # individual nodes has been deleted before continuing, so verify
+  # that it is missing here.
+  - name: Ensure node directories and tarballs are absent from generated configs
+    shell: >
+      rm -rf {{ openshift.common.config_base }}/generated-configs/node-*
+    args:
+      warn: no
+
+- name: Redeploy node certificates
+  hosts: oo_nodes_to_config
+  pre_tasks:
+  - name: Remove CA certificate
+    file:
+      path: "{{ item }}"
+      state: absent
+    with_items:
+    - "{{ openshift.common.config_base }}/node/ca.crt"
diff --git a/playbooks/openshift-node/private/redeploy-certificates.yml b/playbooks/openshift-node/private/redeploy-certificates.yml
new file mode 100644
index 000000000..3bd38a61d
--- /dev/null
+++ b/playbooks/openshift-node/private/redeploy-certificates.yml
@@ -0,0 +1,6 @@
+---
+- include: certificates-backup.yml
+
+- include: certificates.yml
+  vars:
+    openshift_certificates_redeploy: true
diff --git a/playbooks/openshift-node/redeploy-certificates.yml b/playbooks/openshift-node/redeploy-certificates.yml
new file mode 100644
index 000000000..df727247b
--- /dev/null
+++ b/playbooks/openshift-node/redeploy-certificates.yml
@@ -0,0 +1,6 @@
+---
+- include: ../init/main.yml
+
+- include: private/redeploy-certificates.yml
+
+- include: private/restart.yml
diff --git a/playbooks/redeploy-certificates.yml b/playbooks/redeploy-certificates.yml
new file mode 100644
index 000000000..45135c10e
--- /dev/null
+++ b/playbooks/redeploy-certificates.yml
@@ -0,0 +1,26 @@
+---
+- include: init/main.yml
+
+- include: openshift-etcd/private/redeploy-certificates.yml
+
+- include: openshift-master/private/redeploy-certificates.yml
+
+- include: openshift-node/private/redeploy-certificates.yml
+
+- include: openshift-etcd/private/restart.yml
+  vars:
+    g_etcd_certificates_expired: "{{ ('expired' in (hostvars | oo_select_keys(groups['etcd']) | oo_collect('check_results.check_results.etcd') | oo_collect('health'))) | bool }}"
+
+- include: openshift-master/private/restart.yml
+
+- include: openshift-node/private/restart.yml
+
+- include: openshift-hosted/private/redeploy-router-certificates.yml
+  when: openshift_hosted_manage_router | default(true) | bool
+
+- include: openshift-hosted/private/redeploy-registry-certificates.yml
+  when: openshift_hosted_manage_registry | default(true) | bool
+
+- include: openshift-master/private/revert-client-ca.yml
+
+- include: openshift-master/private/restart.yml
-- 
cgit v1.2.3