diff --git a/inventory/sample/group_vars/k8s-cluster.yml b/inventory/sample/group_vars/k8s-cluster.yml
index 69436895486ad3246c28199e6ea9a341bb30b98b..96a301f7da1210d864d0656bb9322a093d07c3b8 100644
--- a/inventory/sample/group_vars/k8s-cluster.yml
+++ b/inventory/sample/group_vars/k8s-cluster.yml
@@ -207,6 +207,10 @@ ingress_nginx_enabled: false
 # ingress_nginx_configmap_udp_services:
 #   53: "kube-system/kube-dns:53"
 
+# Cert manager deployment
+cert_manager_enabled: false
+# cert_manager_namespace: "cert-manager"
+
 # Add Persistent Volumes Storage Class for corresponding cloud provider ( OpenStack is only supported now )
 persistent_volumes_enabled: false
 
diff --git a/roles/download/defaults/main.yml b/roles/download/defaults/main.yml
index 74594ead3b5a3209b03e6b1ac588b27ab930adbe..21b6bc72d6b9b41f84a52627bc0eddc057571838 100644
--- a/roles/download/defaults/main.yml
+++ b/roles/download/defaults/main.yml
@@ -124,7 +124,6 @@ fluentd_image_tag: "{{ fluentd_version }}"
 kibana_version: "v4.6.1"
 kibana_image_repo: "gcr.io/google_containers/kibana"
 kibana_image_tag: "{{ kibana_version }}"
-
 helm_version: "v2.8.1"
 helm_image_repo: "lachlanevenson/k8s-helm"
 helm_image_tag: "{{ helm_version }}"
@@ -132,6 +131,11 @@ tiller_image_repo: "gcr.io/kubernetes-helm/tiller"
 tiller_image_tag: "{{ helm_version }}"
 vault_image_repo: "vault"
 vault_image_tag: "{{ vault_version }}"
+cert_manager_version: "v0.2.3"
+cert_manager_controller_image_repo: "quay.io/jetstack/cert-manager-controller"
+cert_manager_controller_image_tag: "{{ cert_manager_version }}"
+cert_manager_ingress_shim_image_repo: "quay.io/jetstack/cert-manager-ingress-shim"
+cert_manager_ingress_shim_image_tag: "{{ cert_manager_version }}"
 
 downloads:
   netcheck_server:
@@ -422,6 +426,22 @@ downloads:
     version: "{{ vault_version }}"
     groups:
       - vault
+  cert_manager_controller:
+    enabled: "{{ cert_manager_enabled }}"
+    container: true
+    repo: "{{ cert_manager_controller_image_repo }}"
+    tag: "{{ cert_manager_controller_image_tag }}"
+    sha256: "{{ cert_manager_controller_digest_checksum|default(None) }}"
+    groups:
+      - kube-node
+  cert_manager_ingress_shim:
+    enabled: "{{ cert_manager_enabled }}"
+    container: true
+    repo: "{{ cert_manager_ingress_shim_image_repo }}"
+    tag: "{{ cert_manager_ingress_shim_image_tag }}"
+    sha256: "{{ cert_manager_ingress_shim_digest_checksum|default(None) }}"
+    groups:
+      - kube-node
 
 download_defaults:
   container: false
diff --git a/roles/etcd/defaults/main.yml b/roles/etcd/defaults/main.yml
index 1268c13c7c7d93c74895edcdab75bbd3ca12391b..6c13810c525daecd5055c9f0a76431437b4edc98 100644
--- a/roles/etcd/defaults/main.yml
+++ b/roles/etcd/defaults/main.yml
@@ -22,12 +22,12 @@ etcd_script_dir: "{{ bin_dir }}/etcd-scripts"
 etcd_heartbeat_interval: "250"
 etcd_election_timeout: "5000"
 
-#etcd_snapshot_count: "10000"
+# etcd_snapshot_count: "10000"
 
 # Parameters for ionice
 # -c takes an integer between 0 and 3 or one of the strings none, realtime, best-effort or idle.
 # -n takes an integer between 0 (highest priority) and 7 (lowest priority)
-#etcd_ionice: "-c2 -n0"
+# etcd_ionice: "-c2 -n0"
 
 etcd_metrics: "basic"
 
diff --git a/roles/kubernetes-apps/ingress_controller/cert_manager/README.md b/roles/kubernetes-apps/ingress_controller/cert_manager/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..b0f008676a1c63fcc0a3da7dab4937b9e202d4fa
--- /dev/null
+++ b/roles/kubernetes-apps/ingress_controller/cert_manager/README.md
@@ -0,0 +1,17 @@
+Deployment files
+================
+
+This directory contains example deployment manifests for cert-manager that can
+be used in place of the official Helm chart.
+
+This is useful if you are deploying cert-manager into an environment without
+Helm, or want to inspect a 'bare minimum' deployment.
+
+Where do these come from?
+-------------------------
+
+The manifests in these subdirectories are generated from the Helm chart
+automatically. The `values.yaml` files used to configure cert-manager can be
+found in [`hack/deploy`](../../hack/deploy/).
+
+They are automatically generated by running `./hack/update-deploy-gen.sh`.
diff --git a/roles/kubernetes-apps/ingress_controller/cert_manager/defaults/main.yml b/roles/kubernetes-apps/ingress_controller/cert_manager/defaults/main.yml
new file mode 100644
index 0000000000000000000000000000000000000000..bc6bceb151eac7fa7ec872129decceec3e6a5cfc
--- /dev/null
+++ b/roles/kubernetes-apps/ingress_controller/cert_manager/defaults/main.yml
@@ -0,0 +1,6 @@
+---
+cert_manager_namespace: "cert-manager"
+cert_manager_cpu_requests: 10m
+cert_manager_cpu_limits: 30m
+cert_manager_memory_requests: 32Mi
+cert_manager_memory_limits: 200Mi
diff --git a/roles/kubernetes-apps/ingress_controller/cert_manager/tasks/main.yml b/roles/kubernetes-apps/ingress_controller/cert_manager/tasks/main.yml
new file mode 100644
index 0000000000000000000000000000000000000000..eeb29da2d441a5af4a63520e4e54eb093936ce3e
--- /dev/null
+++ b/roles/kubernetes-apps/ingress_controller/cert_manager/tasks/main.yml
@@ -0,0 +1,38 @@
+---
+
+- name: Cert Manager | Create addon dir
+  file:
+    path: "{{ kube_config_dir }}/addons/cert_manager"
+    state: directory
+    owner: root
+    group: root
+    mode: 0755
+
+- name: Cert Manager | Create manifests
+  template:
+    src: "{{ item.file }}.j2"
+    dest: "{{ kube_config_dir }}/addons/cert_manager/{{ item.file }}"
+  with_items:
+    - { name: cert-manager-ns, file: cert-manager-ns.yml, type: ns }
+    - { name: cert-manager-sa, file: cert-manager-sa.yml, type: sa }
+    - { name: cert-manager-clusterrole, file: cert-manager-clusterrole.yml, type: clusterrole }
+    - { name: cert-manager-clusterrolebinding, file: cert-manager-clusterrolebinding.yml, type: clusterrolebinding }
+    - { name: cert-manager-issuer-crd, file: cert-manager-issuer-crd.yml, type: crd }
+    - { name: cert-manager-clusterissuer-crd, file: cert-manager-clusterissuer-crd.yml, type: crd }
+    - { name: cert-manager-certificate-crd, file: cert-manager-certificate-crd.yml, type: crd }
+    - { name: cert-manager-deploy, file: cert-manager-deploy.yml, type: deploy }
+  register: cert_manager_manifests
+  when:
+    - inventory_hostname == groups['kube-master'][0]
+
+- name: Cert Manager | Apply manifests
+  kube:
+    name: "{{ item.item.name }}"
+    namespace: "{{ cert_manager_namespace }}"
+    kubectl: "{{ bin_dir }}/kubectl"
+    resource: "{{ item.item.type }}"
+    filename: "{{ kube_config_dir }}/addons/cert_manager/{{ item.item.file }}"
+    state: "latest"
+  with_items: "{{ cert_manager_manifests.results }}"
+  when:
+    - inventory_hostname == groups['kube-master'][0]
diff --git a/roles/kubernetes-apps/ingress_controller/cert_manager/templates/cert-manager-certificate-crd.yml.j2 b/roles/kubernetes-apps/ingress_controller/cert_manager/templates/cert-manager-certificate-crd.yml.j2
new file mode 100644
index 0000000000000000000000000000000000000000..48d0c5b49ea947e6673da6261dcaad4be950a1b7
--- /dev/null
+++ b/roles/kubernetes-apps/ingress_controller/cert_manager/templates/cert-manager-certificate-crd.yml.j2
@@ -0,0 +1,21 @@
+---
+apiVersion: apiextensions.k8s.io/v1beta1
+kind: CustomResourceDefinition
+metadata:
+  name: certificates.certmanager.k8s.io
+  labels:
+    app: cert-manager
+    chart: cert-manager-0.2.5
+    release: cert-manager
+    heritage: Tiller
+spec:
+  group: certmanager.k8s.io
+  version: v1alpha1
+  scope: Namespaced
+  names:
+    kind: Certificate
+    plural: certificates
+    shortNames:
+      - cert
+      - certs
+      
diff --git a/roles/kubernetes-apps/ingress_controller/cert_manager/templates/cert-manager-clusterissuer-crd.yml.j2 b/roles/kubernetes-apps/ingress_controller/cert_manager/templates/cert-manager-clusterissuer-crd.yml.j2
new file mode 100644
index 0000000000000000000000000000000000000000..86601e098d1f3f68f4d0559cf8dc5867738926c0
--- /dev/null
+++ b/roles/kubernetes-apps/ingress_controller/cert_manager/templates/cert-manager-clusterissuer-crd.yml.j2
@@ -0,0 +1,17 @@
+---
+apiVersion: apiextensions.k8s.io/v1beta1
+kind: CustomResourceDefinition
+metadata:
+  name: clusterissuers.certmanager.k8s.io
+  labels:
+    app: cert-manager
+    chart: cert-manager-0.2.5
+    release: cert-manager
+    heritage: Tiller
+spec:
+  group: certmanager.k8s.io
+  version: v1alpha1
+  names:
+    kind: ClusterIssuer
+    plural: clusterissuers
+  scope: Cluster
diff --git a/roles/kubernetes-apps/ingress_controller/cert_manager/templates/cert-manager-clusterrole.yml.j2 b/roles/kubernetes-apps/ingress_controller/cert_manager/templates/cert-manager-clusterrole.yml.j2
new file mode 100644
index 0000000000000000000000000000000000000000..9d36de5cb123f678c2956358ccabd138a2aacc25
--- /dev/null
+++ b/roles/kubernetes-apps/ingress_controller/cert_manager/templates/cert-manager-clusterrole.yml.j2
@@ -0,0 +1,25 @@
+---
+apiVersion: rbac.authorization.k8s.io/v1beta1
+kind: ClusterRole
+metadata:
+  name: cert-manager
+  labels:
+    app: cert-manager
+    chart: cert-manager-0.2.5
+    release: cert-manager
+    heritage: Tiller
+rules:
+  - apiGroups: ["certmanager.k8s.io"]
+    resources: ["certificates", "issuers", "clusterissuers"]
+    verbs: ["*"]
+  - apiGroups: [""]
+    # TODO: remove endpoints once 0.4 is released. We include it here in case
+    # users use the 'master' version of the Helm chart with a 0.2.x release of
+    # cert-manager that still performs leader election with Endpoint resources.
+    # We advise users don't do this, but some will anyway and this will reduce
+    # friction.
+    resources: ["endpoints", "configmaps", "secrets", "events", "services", "pods"]
+    verbs: ["*"]
+  - apiGroups: ["extensions"]
+    resources: ["ingresses"]
+    verbs: ["*"]
diff --git a/roles/kubernetes-apps/ingress_controller/cert_manager/templates/cert-manager-clusterrolebinding.yml.j2 b/roles/kubernetes-apps/ingress_controller/cert_manager/templates/cert-manager-clusterrolebinding.yml.j2
new file mode 100644
index 0000000000000000000000000000000000000000..d0e481c6cc8aa4e2b386f11d20bbd2a8a76d0ea5
--- /dev/null
+++ b/roles/kubernetes-apps/ingress_controller/cert_manager/templates/cert-manager-clusterrolebinding.yml.j2
@@ -0,0 +1,18 @@
+---
+apiVersion: rbac.authorization.k8s.io/v1beta1
+kind: ClusterRoleBinding
+metadata:
+  name: cert-manager
+  labels:
+    app: cert-manager
+    chart: cert-manager-0.2.5
+    release: cert-manager
+    heritage: Tiller
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: cert-manager
+subjects:
+  - name: cert-manager
+    namespace: {{ cert_manager_namespace }}
+    kind: ServiceAccount
diff --git a/roles/kubernetes-apps/ingress_controller/cert_manager/templates/cert-manager-deploy.yml.j2 b/roles/kubernetes-apps/ingress_controller/cert_manager/templates/cert-manager-deploy.yml.j2
new file mode 100644
index 0000000000000000000000000000000000000000..ef66bef0523d395e81ef3811b8913f959a3f9ce3
--- /dev/null
+++ b/roles/kubernetes-apps/ingress_controller/cert_manager/templates/cert-manager-deploy.yml.j2
@@ -0,0 +1,51 @@
+---
+apiVersion: apps/v1beta1
+kind: Deployment
+metadata:
+  name: cert-manager
+  namespace: {{ cert_manager_namespace }}
+  labels:
+    app: cert-manager
+    chart: cert-manager-0.2.5
+    release: cert-manager
+    heritage: Tiller
+spec:
+  replicas: 1
+  template:
+    metadata:
+      labels:
+        k8s-app: cert-manager
+        release: cert-manager
+      annotations:
+    spec:
+      serviceAccountName: cert-manager
+      containers:
+        - name: cert-manager
+          image: {{ cert_manager_controller_image_repo }}:{{ cert_manager_controller_image_tag }}
+          imagePullPolicy: {{ k8s_image_pull_policy }}
+          args:
+            - --cluster-resource-namespace=$(POD_NAMESPACE)
+          env:
+            - name: POD_NAMESPACE
+              valueFrom:
+                fieldRef:
+                  fieldPath: metadata.namespace
+          resources:
+            requests:
+              cpu: {{ cert_manager_cpu_requests }}
+              memory: {{ cert_manager_memory_requests }}
+            limits:
+              cpu: {{ cert_manager_cpu_limits }}
+              memory: {{ cert_manager_memory_limits }}
+            
+        - name: ingress-shim
+          image: {{ cert_manager_ingress_shim_image_repo }}:{{ cert_manager_ingress_shim_image_tag }}
+          imagePullPolicy: {{ k8s_image_pull_policy }}
+          resources:
+            requests:
+              cpu: {{ cert_manager_cpu_requests }}
+              memory: {{ cert_manager_memory_requests }}
+            limits:
+              cpu: {{ cert_manager_cpu_limits }}
+              memory: {{ cert_manager_memory_limits }}
+            
diff --git a/roles/kubernetes-apps/ingress_controller/cert_manager/templates/cert-manager-issuer-crd.yml.j2 b/roles/kubernetes-apps/ingress_controller/cert_manager/templates/cert-manager-issuer-crd.yml.j2
new file mode 100644
index 0000000000000000000000000000000000000000..7e344d9f9a666f043f6a6cb3f3e3a89f5670446c
--- /dev/null
+++ b/roles/kubernetes-apps/ingress_controller/cert_manager/templates/cert-manager-issuer-crd.yml.j2
@@ -0,0 +1,17 @@
+---
+apiVersion: apiextensions.k8s.io/v1beta1
+kind: CustomResourceDefinition
+metadata:
+  name: issuers.certmanager.k8s.io
+  labels:
+    app: cert-manager
+    chart: cert-manager-0.2.5
+    release: cert-manager
+    heritage: Tiller
+spec:
+  group: certmanager.k8s.io
+  version: v1alpha1
+  names:
+    kind: Issuer
+    plural: issuers
+  scope: Namespaced
diff --git a/roles/kubernetes-apps/ingress_controller/cert_manager/templates/cert-manager-ns.yml.j2 b/roles/kubernetes-apps/ingress_controller/cert_manager/templates/cert-manager-ns.yml.j2
new file mode 100644
index 0000000000000000000000000000000000000000..7cf3a282dc113c6b615406b050116b91df9f1db5
--- /dev/null
+++ b/roles/kubernetes-apps/ingress_controller/cert_manager/templates/cert-manager-ns.yml.j2
@@ -0,0 +1,7 @@
+---
+apiVersion: v1
+kind: Namespace
+metadata:
+  name: {{ cert_manager_namespace }}
+  labels:
+    name: {{ cert_manager_namespace }}
diff --git a/roles/kubernetes-apps/ingress_controller/cert_manager/templates/cert-manager-sa.yml.j2 b/roles/kubernetes-apps/ingress_controller/cert_manager/templates/cert-manager-sa.yml.j2
new file mode 100644
index 0000000000000000000000000000000000000000..ccdd5f430c118fa7b37d3f923aa324bb77a92781
--- /dev/null
+++ b/roles/kubernetes-apps/ingress_controller/cert_manager/templates/cert-manager-sa.yml.j2
@@ -0,0 +1,11 @@
+---
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: cert-manager
+  namespace: {{ cert_manager_namespace }}
+  labels:
+    app: cert-manager
+    chart: cert-manager-0.2.5
+    release: cert-manager
+    heritage: Tiller
diff --git a/roles/kubernetes-apps/ingress_controller/meta/main.yml b/roles/kubernetes-apps/ingress_controller/meta/main.yml
index da2e03ecc0d30630cfb7b32c1806991891c9261e..617e9d9a7ccecc4e26d36025f11dc090dc41b7d8 100644
--- a/roles/kubernetes-apps/ingress_controller/meta/main.yml
+++ b/roles/kubernetes-apps/ingress_controller/meta/main.yml
@@ -6,3 +6,10 @@ dependencies:
       - apps
       - ingress-nginx
       - ingress-controller
+
+  - role: kubernetes-apps/ingress_controller/cert_manager
+    when: cert_manager_enabled
+    tags:
+      - apps
+      - cert-manager
+      - ingress-controller
diff --git a/roles/kubernetes/master/defaults/main.yml b/roles/kubernetes/master/defaults/main.yml
index 303c1a88a366bd74810d39746c274229d109d152..6325bb31cedcdc7b4ddb194d3f72893426c822fe 100644
--- a/roles/kubernetes/master/defaults/main.yml
+++ b/roles/kubernetes/master/defaults/main.yml
@@ -96,4 +96,5 @@ volume_cross_zone_attachment: false
 ## Encrypting Secret Data at Rest
 kube_encrypt_secret_data: false
 kube_encrypt_token: "{{ lookup('password', inventory_dir + '/credentials/kube_encrypt_token.creds length=32 chars=ascii_letters,digits') }}"
-kube_encryption_algorithm: "aescbc" # Must be either: aescbc, secretbox or aesgcm
+# Must be either: aescbc, secretbox or aesgcm
+kube_encryption_algorithm: "aescbc"
diff --git a/roles/kubespray-defaults/defaults/main.yaml b/roles/kubespray-defaults/defaults/main.yaml
index b6f46eb5aa86d6eefb279bd19ac50dbcbf01c375..d6217d654e6011d458fc5b7c29547397672a461a 100644
--- a/roles/kubespray-defaults/defaults/main.yaml
+++ b/roles/kubespray-defaults/defaults/main.yaml
@@ -174,6 +174,7 @@ local_volume_provisioner_enabled: "{{ local_volumes_enabled | default('false') }
 persistent_volumes_enabled: false
 cephfs_provisioner_enabled: false
 ingress_nginx_enabled: false
+cert_manager_enabled: false
 
 ## When OpenStack is used, Cinder version can be explicitly specified if autodetection fails (Fixed in 1.9: https://github.com/kubernetes/kubernetes/issues/50461)
 # openstack_blockstorage_version: "v1/v2/auto (default)"
diff --git a/roles/network_plugin/calico/defaults/main.yml b/roles/network_plugin/calico/defaults/main.yml
index 1b0cd0421dfba443cd953848222dd3355d326181..857ebd11aac4400a67ecc5110d067933969ff915 100644
--- a/roles/network_plugin/calico/defaults/main.yml
+++ b/roles/network_plugin/calico/defaults/main.yml
@@ -50,4 +50,4 @@ rbac_resources:
 # * can-reach=DESTINATION
 # * interface=INTERFACE-REGEX
 # see https://docs.projectcalico.org/v3.0/reference/node/configuration#ip-autodetection-methods
-#calico_ip_auto_method: "interface=eth.*"
+# calico_ip_auto_method: "interface=eth.*"
diff --git a/tests/files/gce_centos7-flannel-addons.yml b/tests/files/gce_centos7-flannel-addons.yml
index 8ac8a901b62218affc5ebc6891b89c38979661f2..9e2e1083fe0339ed784d5477b3889f8368995ba7 100644
--- a/tests/files/gce_centos7-flannel-addons.yml
+++ b/tests/files/gce_centos7-flannel-addons.yml
@@ -16,3 +16,5 @@ deploy_netchecker: true
 kubedns_min_replicas: 1
 cloud_provider: gce
 kube_encrypt_secret_data: true
+ingress_nginx_enabled: true
+cert_manager_enabled: true