summaryrefslogtreecommitdiffstats
path: root/installer/roles/kubernetes/tasks/main.yml
blob: faff3a83b22554677c7e60c62af7911a172a8085 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
---
- fail:
    msg: "Only set one of kubernetes_context or openshift_host"
  when: openshift_host is defined and kubernetes_context is defined

- include_tasks: "{{ tasks }}"
  with_items:
    - openshift_auth.yml
    - openshift.yml
  loop_control:
    loop_var: tasks
  when: openshift_host is defined

- include_tasks: "{{ tasks }}"
  with_items:
    - kubernetes_auth.yml
    - kubernetes.yml
  loop_control:
    loop_var: tasks
  when: kubernetes_context is defined

- name: Use kubectl or oc
  set_fact:
    kubectl_or_oc: "{{ openshift_oc_bin if openshift_oc_bin is defined else 'kubectl' }}"

- set_fact:
    deployment_object: "sts"

- name: Record deployment size
  shell: |
    {{ kubectl_or_oc }} get {{ deployment_object }} \
      {{ kubernetes_deployment_name }} \
      -n {{ kubernetes_namespace }} -o=jsonpath='{.status.replicas}'
  register: deployment_details
  ignore_errors: true

- name: Set expected post-deployment Replicas value
  set_fact:
    kubernetes_deployment_replica_size: "{{ deployment_details.stdout | int }}"
  when: deployment_details.rc == 0

- name: Delete existing Deployment
  shell: |
    {{ kubectl_or_oc }} delete {{ deployment_object }} \
      {{ kubernetes_deployment_name }} -n {{ kubernetes_namespace }}
  when: deployment_details.rc == 0

- name: Get Postgres Service Detail
  shell: "{{ kubectl_or_oc }} describe svc {{ postgresql_service_name }} -n {{ kubernetes_namespace }}"
  register: postgres_svc_details
  ignore_errors: true
  when: "pg_hostname is not defined or pg_hostname == ''"

- name: Deploy PostgreSQL (OpenShift)
  block:
    - name: Template PostgreSQL Deployment (OpenShift)
      template:
        src: postgresql-persistent.yml.j2
        dest: "{{ kubernetes_base_path }}/postgresql-persistent.yml"
        mode: '0600'

    - name: Deploy and Activate Postgres (OpenShift)
      shell: |
        {{ openshift_oc_bin }} new-app --file={{ kubernetes_base_path }}/postgresql-persistent.yml \
          -e MEMORY_LIMIT={{ pg_memory_limit|default('512') }}Mi \
          -e DATABASE_SERVICE_NAME=postgresql  \
          -e POSTGRESQL_MAX_CONNECTIONS={{ pg_max_connections|default(1024) }} \
          -e POSTGRESQL_USER={{ pg_username }} \
          -e POSTGRESQL_PASSWORD={{ pg_password | quote }} \
          -e POSTGRESQL_ADMIN_PASSWORD={{ pg_admin_password | quote }} \
          -e POSTGRESQL_DATABASE={{ pg_database }} \
          -e POSTGRESQL_VERSION=10 \
          -n {{ kubernetes_namespace }}
      register: openshift_pg_activate
      no_log: true
  when:
    - pg_hostname is not defined or pg_hostname == ''
    - postgres_svc_details is defined and postgres_svc_details.rc != 0
    - openshift_host is defined

- name: Deploy PostgreSQL (Kubernetes)
  block:
    - name: Template PostgreSQL Deployment (Kubernetes)
      set_fact:
        pg_values: "{{ lookup('template', 'postgresql-values.yml.j2') }}"
      no_log: true

    - name: Deploy and Activate Postgres (Kubernetes)
      shell: |
        helm repo update --tiller-namespace={{ tiller_namespace | default('kube-system') }}
        echo {{ pg_values | quote }} | helm upgrade {{ postgresql_service_name }} --install \
          --namespace {{ kubernetes_namespace }} \
          --version="6.2.1" \
          --tiller-namespace={{ tiller_namespace | default('kube-system') }} \
          --values - \
          stable/postgresql
      register: kubernetes_pg_activate
      no_log: true
  when:
    - pg_hostname is not defined or pg_hostname == ''
    - postgres_svc_details is defined and postgres_svc_details.rc != 0
    - kubernetes_context is defined

- name: Set postgresql hostname to helm package service (Kubernetes)
  set_fact:
    pg_hostname: "{{ postgresql_service_name }}"
  when:
    - pg_hostname is not defined or pg_hostname == ''
    - kubernetes_context is defined

- name: Wait for Postgres to activate
  pause:
    seconds: "{{ postgress_activate_wait }}"
  when: openshift_pg_activate.changed or kubernetes_pg_activate.changed

- name: Check postgres version and upgrade Postgres if necessary
  block:
    - name: Check if Postgres 9.6 is being used
      shell: |
        POD=$({{ kubectl_or_oc }} -n {{ kubernetes_namespace }} \
          get pods -l=name=postgresql --field-selector status.phase=Running -o jsonpath="{.items[0].metadata.name}")
        oc exec $POD -n {{ kubernetes_namespace }} -- bash -c "psql -tAc 'select version()'"
      register: pg_version
    - name: Upgrade postgres if necessary
      block:
        - name: Set new pg image
          shell: |
            IMAGE=registry.access.redhat.com/rhscl/postgresql-10-rhel7
            {{ kubectl_or_oc }} -n {{ kubernetes_namespace }} set image dc/postgresql postgresql=$IMAGE

        - name: Wait for change to take affect
          pause:
            seconds: 5

        - name: Set env var for pg upgrade
          shell: |
            {{ kubectl_or_oc }} -n {{ kubernetes_namespace }} set env dc/postgresql POSTGRESQL_UPGRADE=copy

        - name: Wait for change to take affect
          pause:
            seconds: 5

        - name: Set env var for new pg version
          shell: |
            {{ kubectl_or_oc }} -n {{ kubernetes_namespace }} set env dc/postgresql POSTGRESQL_VERSION=10

        - name: Wait for Postgres to redeploy
          pause:
            seconds: "{{ postgress_activate_wait }}"

        - name: Wait for Postgres to finish upgrading
          shell: |
            POD=$({{ kubectl_or_oc }} -n {{ kubernetes_namespace }} \
              get pods -l=name=postgresql -o jsonpath="{.items[0].metadata.name}")
            {{ kubectl_or_oc }} -n {{ kubernetes_namespace }} logs $POD | grep 'Upgrade DONE'
          register: pg_upgrade_logs
          retries: 360
          delay: 10
          until: pg_upgrade_logs is success

        - name: Unset upgrade env var
          shell: |
            {{ kubectl_or_oc }} -n {{ kubernetes_namespace }} set env dc/postgresql POSTGRESQL_UPGRADE-

        - name: Wait for Postgres to redeploy
          pause:
            seconds: "{{ postgress_activate_wait }}"
      when: "pg_version is success and '9.6' in pg_version.stdout"
  when:
    - pg_hostname is not defined or pg_hostname == ''

- name: Set image names if using custom registry
  block:
    - name: Set task image name
      set_fact:
        kubernetes_task_image: "{{ docker_registry }}/{{ docker_registry_repository }}/{{ task_image }}"
      when: kubernetes_task_image is not defined

    - name: Set web image name
      set_fact:
        kubernetes_web_image: "{{ docker_registry }}/{{ docker_registry_repository }}/{{ web_image }}"
      when: kubernetes_web_image is not defined
  when: docker_registry is defined

- name: Generate SSL certificates for RabbitMQ, if needed
  include_tasks: ssl_cert_gen.yml
  when: "rabbitmq_use_ssl|default(False)|bool"

- name: Get Kubernetes API version
  command: |
    {{ kubectl_or_oc }} version -o json
  register: kube_version

- name: Extract server version from command output
  set_fact:
    kube_api_version: "{{ (kube_version.stdout | from_json).serverVersion.gitVersion[1:] }}"

- name: Determine StatefulSet api version
  set_fact:
    kubernetes_statefulset_api_version: "{{ 'apps/v1' if kube_api_version is version('1.9', '>=') else 'apps/v1beta1' }}"

- name: Render deployment templates
  set_fact:
    "{{ item }}": "{{ lookup('template', item + '.yml.j2') }}"
  with_items:
    - 'configmap'
    - 'deployment'
    - 'secret'
  no_log: true

- name: Apply Deployment
  shell: |
    echo {{ item | quote }} | {{ kubectl_or_oc }} apply -f -
  with_items:
    - "{{ configmap }}"
    - "{{ deployment }}"
    - "{{ secret }}"
  no_log: true

- name: Delete any existing management pod
  shell: |
    {{ kubectl_or_oc }} -n {{ kubernetes_namespace }} \
      delete pod ansible-tower-management --grace-period=0 --ignore-not-found

- name: Template management pod
  set_fact:
    management_pod: "{{ lookup('template', 'management-pod.yml.j2') }}"

- name: Create management pod
  shell: |
    echo {{ management_pod | quote }} | {{ kubectl_or_oc }} apply -f -

- name: Wait for management pod to start
  shell: |
    {{ kubectl_or_oc }} -n {{ kubernetes_namespace }} \
      get pod ansible-tower-management -o jsonpath="{.status.phase}"
  register: result
  until: result.stdout == "Running"
  retries: 60
  delay: 10

- name: Migrate database
  shell: |
    {{ kubectl_or_oc }} -n {{ kubernetes_namespace }} exec ansible-tower-management -- \
      bash -c "awx-manage migrate --noinput"

- name: Check for Tower Super users
  shell: |
    {{ kubectl_or_oc }} -n {{ kubernetes_namespace }} exec ansible-tower-management -- \
      bash -c "echo 'from django.contrib.auth.models import User; nsu = User.objects.filter(is_superuser=True).count(); exit(0 if nsu > 0 else 1)' | awx-manage shell"
  register: super_check
  ignore_errors: true
  changed_when: super_check.rc > 0

- name: create django super user if it does not exist
  shell: |
    {{ kubectl_or_oc }} -n {{ kubernetes_namespace }} exec ansible-tower-management -- \
      bash -c "echo \"from django.contrib.auth.models import User; User.objects.create_superuser('{{ admin_user }}', '{{ admin_email }}', '{{ admin_password }}')\" | awx-manage shell"
  no_log: true
  when: super_check.rc > 0

- name: update django super user password
  shell: |
    {{ kubectl_or_oc }} -n {{ kubernetes_namespace }} exec ansible-tower-management -- \
      bash -c "awx-manage update_password --username='{{ admin_user }}' --password='{{ admin_password }}'"
  no_log: true
  register: result
  changed_when: "'Password updated' in result.stdout"

- name: Create the default organization if it is needed.
  shell: |
    {{ kubectl_or_oc }} -n {{ kubernetes_namespace }} exec ansible-tower-management -- \
      bash -c "awx-manage create_preload_data"
  register: cdo
  changed_when: "'added' in cdo.stdout"
  when: create_preload_data | bool

- name: Delete management pod
  shell: |
    {{ kubectl_or_oc }} -n {{ kubernetes_namespace }} \
      delete pod ansible-tower-management --grace-period=0 --ignore-not-found

- name: Scale up deployment
  shell: |
    {{ kubectl_or_oc }} -n {{ kubernetes_namespace }} \
      scale {{ deployment_object }} {{ kubernetes_deployment_name }} --replicas=0
    {{ kubectl_or_oc }} -n {{ kubernetes_namespace }} \
      scale {{ deployment_object }} {{ kubernetes_deployment_name }} --replicas={{ kubernetes_deployment_replica_size }}