From 572d8ca678e72812f5a06ad41d599d7e6b6f169d Mon Sep 17 00:00:00 2001 From: Jason O'Donnell <2160810+jasonodonnell@users.noreply.github.com> Date: Wed, 10 Apr 2019 10:49:52 -0400 Subject: [PATCH] Add ansible playbooks and documentation --- .gitignore | 1 + ansible/README.md | 15 + ansible/ansible.cfg | 5 + ansible/crunchy_logo.png | Bin 0 -> 403323 bytes ansible/inventory | 138 ++++ ansible/main.yml | 10 + ansible/roles/pgo-metrics/defaults/main.yml | 9 + ansible/roles/pgo-metrics/tasks/cleanup.yml | 79 ++ ansible/roles/pgo-metrics/tasks/grafana.yml | 54 ++ .../roles/pgo-metrics/tasks/kubernetes.yml | 11 + .../pgo-metrics/tasks/kubernetes_auth.yml | 4 + ansible/roles/pgo-metrics/tasks/main.yml | 42 ++ ansible/roles/pgo-metrics/tasks/openshift.yml | 11 + .../pgo-metrics/tasks/openshift_auth.yml | 25 + .../pgo-metrics/tasks/preflight-grafana.yml | 17 + .../tasks/preflight-prometheus.yml | 12 + .../roles/pgo-metrics/tasks/prometheus.yml | 45 ++ .../templates/grafana-deployment.json.j2 | 89 +++ .../pgo-metrics/templates/grafana-pvc.json.j2 | 18 + .../templates/grafana-secret.json.j2 | 12 + .../templates/grafana-service.json.j2 | 26 + .../templates/prometheus-deployment.json.j2 | 63 ++ .../templates/prometheus-pvc.json.j2 | 18 + .../templates/prometheus-rbac.json.j2 | 51 ++ .../templates/prometheus-service.json.j2 | 26 + ansible/roles/pgo-metrics/vars/openshift.yml | 2 + ansible/roles/pgo-operator/defaults/main.yml | 20 + .../files/crds/pgbackups-crd.yaml | 14 + .../files/crds/pgclusters-crd.yaml | 14 + .../files/crds/pgpolicies-crd.yaml | 14 + .../files/crds/pgreplicas-crd.yaml | 14 + .../pgo-operator/files/crds/pgtasks-crd.yaml | 14 + .../files/pgo-backrest-repo/aws-s3-ca.crt | 21 + .../files/pgo-backrest-repo/config | 5 + .../files/pgo-backrest-repo/sshd_config | 139 ++++ .../pgo-operator/files/pgo-configs/README.txt | 2 + .../files/pgo-configs/affinity.json | 16 + .../files/pgo-configs/backrest-job.json | 80 +++ .../pgo-configs/backrest-restore-job.json | 94 +++ .../files/pgo-configs/backup-job.json | 71 ++ .../files/pgo-configs/cluster-deployment.json | 199 +++++ .../files/pgo-configs/cluster-roles.yaml | 32 + .../files/pgo-configs/cluster-service.json | 52 ++ .../files/pgo-configs/collect.json | 20 + .../pgo-configs/container-resources.json | 10 + .../pgo-configs/pgbackrest-env-vars.json | 33 + .../pgo-configs/pgbackrest-s3-env-vars.json | 18 + .../files/pgo-configs/pgbadger.json | 33 + .../files/pgo-configs/pgbench-job.json | 105 +++ .../files/pgo-configs/pgbouncer-template.json | 86 +++ .../files/pgo-configs/pgbouncer.ini | 22 + .../files/pgo-configs/pgbouncer_hba.conf | 1 + .../files/pgo-configs/pgdump-job.json | 97 +++ .../files/pgo-configs/pgmonitor-env-vars.json | 3 + .../pgo-backrest-repo-service-template.json | 25 + .../pgo-backrest-repo-template.json | 100 +++ .../files/pgo-configs/pgo.load-template.json | 69 ++ .../files/pgo-configs/pgo.lspvc-template.json | 42 ++ .../pgo-configs/pgo.sqlrunner-template.json | 81 +++ .../pgo-operator/files/pgo-configs/pgorole | 2 + .../files/pgo-configs/pgpool-template.json | 83 +++ .../files/pgo-configs/pgpool.conf | 677 ++++++++++++++++++ .../files/pgo-configs/pgrestore-job.json | 94 +++ .../files/pgo-configs/pool_hba.conf | 67 ++ .../files/pgo-configs/pool_passwd | 2 + .../files/pgo-configs/pvc-matchlabels.json | 1 + .../files/pgo-configs/pvc-storageclass.json | 22 + .../pgo-operator/files/pgo-configs/pvc.json | 24 + .../files/pgo-configs/rmdata-job.json | 53 ++ .../pgo-operator/files/pgo-configs/users.txt | 2 + ansible/roles/pgo-operator/files/service.json | 25 + ansible/roles/pgo-operator/tasks/certs.yml | 47 ++ ansible/roles/pgo-operator/tasks/cleanup.yml | 175 +++++ ansible/roles/pgo-operator/tasks/crds.yml | 70 ++ .../roles/pgo-operator/tasks/deprecated.yml | 37 + .../roles/pgo-operator/tasks/kubernetes.yml | 13 + .../pgo-operator/tasks/kubernetes_auth.yml | 4 + ansible/roles/pgo-operator/tasks/main.yml | 201 ++++++ .../roles/pgo-operator/tasks/openshift.yml | 13 + .../pgo-operator/tasks/openshift_auth.yml | 25 + .../roles/pgo-operator/tasks/preflight.yml | 38 + ansible/roles/pgo-operator/tasks/ssh_keys.yml | 36 + .../templates/aws-s3-credentials.yaml.j2 | 3 + .../templates/cluster-rbac.yaml.j2 | 65 ++ .../pgo-operator/templates/deployment.json.j2 | 160 +++++ .../roles/pgo-operator/templates/pgo.yaml.j2 | 78 ++ .../roles/pgo-operator/templates/pgouser.j2 | 1 + .../pgo-operator/templates/pgouser.local.j2 | 1 + .../roles/pgo-operator/templates/rbac.yaml.j2 | 79 ++ ansible/roles/pgo-operator/vars/main.yml | 4 + ansible/roles/pgo-operator/vars/openshift.yml | 2 + .../pgo-preflight/tasks/check_kubernetes.yml | 13 + .../pgo-preflight/tasks/check_openshift.yml | 40 ++ ansible/roles/pgo-preflight/tasks/main.yml | 23 + .../install-with-ansible/_index.md | 28 + .../installation/_index.md | 6 + .../installation/installing-ansible.md | 29 + .../installation/installing-metrics.md | 92 +++ .../installation/installing-operator.md | 111 +++ .../install-with-ansible/prereq/_index.md | 6 + .../prereq/prerequisites.md | 264 +++++++ .../install-with-ansible/uninstall/_index.md | 6 + .../uninstall/uninstalling-metrics.md | 21 + .../uninstall/uninstalling-operator.md | 29 + 104 files changed, 5101 insertions(+) create mode 100644 ansible/README.md create mode 100644 ansible/ansible.cfg create mode 100644 ansible/crunchy_logo.png create mode 100644 ansible/inventory create mode 100644 ansible/main.yml create mode 100644 ansible/roles/pgo-metrics/defaults/main.yml create mode 100644 ansible/roles/pgo-metrics/tasks/cleanup.yml create mode 100644 ansible/roles/pgo-metrics/tasks/grafana.yml create mode 100644 ansible/roles/pgo-metrics/tasks/kubernetes.yml create mode 100644 ansible/roles/pgo-metrics/tasks/kubernetes_auth.yml create mode 100644 ansible/roles/pgo-metrics/tasks/main.yml create mode 100644 ansible/roles/pgo-metrics/tasks/openshift.yml create mode 100644 ansible/roles/pgo-metrics/tasks/openshift_auth.yml create mode 100644 ansible/roles/pgo-metrics/tasks/preflight-grafana.yml create mode 100644 ansible/roles/pgo-metrics/tasks/preflight-prometheus.yml create mode 100644 ansible/roles/pgo-metrics/tasks/prometheus.yml create mode 100644 ansible/roles/pgo-metrics/templates/grafana-deployment.json.j2 create mode 100644 ansible/roles/pgo-metrics/templates/grafana-pvc.json.j2 create mode 100644 ansible/roles/pgo-metrics/templates/grafana-secret.json.j2 create mode 100644 ansible/roles/pgo-metrics/templates/grafana-service.json.j2 create mode 100644 ansible/roles/pgo-metrics/templates/prometheus-deployment.json.j2 create mode 100644 ansible/roles/pgo-metrics/templates/prometheus-pvc.json.j2 create mode 100644 ansible/roles/pgo-metrics/templates/prometheus-rbac.json.j2 create mode 100644 ansible/roles/pgo-metrics/templates/prometheus-service.json.j2 create mode 100644 ansible/roles/pgo-metrics/vars/openshift.yml create mode 100644 ansible/roles/pgo-operator/defaults/main.yml create mode 100644 ansible/roles/pgo-operator/files/crds/pgbackups-crd.yaml create mode 100644 ansible/roles/pgo-operator/files/crds/pgclusters-crd.yaml create mode 100644 ansible/roles/pgo-operator/files/crds/pgpolicies-crd.yaml create mode 100644 ansible/roles/pgo-operator/files/crds/pgreplicas-crd.yaml create mode 100644 ansible/roles/pgo-operator/files/crds/pgtasks-crd.yaml create mode 100644 ansible/roles/pgo-operator/files/pgo-backrest-repo/aws-s3-ca.crt create mode 100644 ansible/roles/pgo-operator/files/pgo-backrest-repo/config create mode 100644 ansible/roles/pgo-operator/files/pgo-backrest-repo/sshd_config create mode 100644 ansible/roles/pgo-operator/files/pgo-configs/README.txt create mode 100644 ansible/roles/pgo-operator/files/pgo-configs/affinity.json create mode 100644 ansible/roles/pgo-operator/files/pgo-configs/backrest-job.json create mode 100644 ansible/roles/pgo-operator/files/pgo-configs/backrest-restore-job.json create mode 100644 ansible/roles/pgo-operator/files/pgo-configs/backup-job.json create mode 100644 ansible/roles/pgo-operator/files/pgo-configs/cluster-deployment.json create mode 100644 ansible/roles/pgo-operator/files/pgo-configs/cluster-roles.yaml create mode 100644 ansible/roles/pgo-operator/files/pgo-configs/cluster-service.json create mode 100644 ansible/roles/pgo-operator/files/pgo-configs/collect.json create mode 100644 ansible/roles/pgo-operator/files/pgo-configs/container-resources.json create mode 100644 ansible/roles/pgo-operator/files/pgo-configs/pgbackrest-env-vars.json create mode 100644 ansible/roles/pgo-operator/files/pgo-configs/pgbackrest-s3-env-vars.json create mode 100644 ansible/roles/pgo-operator/files/pgo-configs/pgbadger.json create mode 100644 ansible/roles/pgo-operator/files/pgo-configs/pgbench-job.json create mode 100644 ansible/roles/pgo-operator/files/pgo-configs/pgbouncer-template.json create mode 100644 ansible/roles/pgo-operator/files/pgo-configs/pgbouncer.ini create mode 100644 ansible/roles/pgo-operator/files/pgo-configs/pgbouncer_hba.conf create mode 100644 ansible/roles/pgo-operator/files/pgo-configs/pgdump-job.json create mode 100644 ansible/roles/pgo-operator/files/pgo-configs/pgmonitor-env-vars.json create mode 100644 ansible/roles/pgo-operator/files/pgo-configs/pgo-backrest-repo-service-template.json create mode 100644 ansible/roles/pgo-operator/files/pgo-configs/pgo-backrest-repo-template.json create mode 100644 ansible/roles/pgo-operator/files/pgo-configs/pgo.load-template.json create mode 100644 ansible/roles/pgo-operator/files/pgo-configs/pgo.lspvc-template.json create mode 100644 ansible/roles/pgo-operator/files/pgo-configs/pgo.sqlrunner-template.json create mode 100644 ansible/roles/pgo-operator/files/pgo-configs/pgorole create mode 100644 ansible/roles/pgo-operator/files/pgo-configs/pgpool-template.json create mode 100644 ansible/roles/pgo-operator/files/pgo-configs/pgpool.conf create mode 100644 ansible/roles/pgo-operator/files/pgo-configs/pgrestore-job.json create mode 100644 ansible/roles/pgo-operator/files/pgo-configs/pool_hba.conf create mode 100644 ansible/roles/pgo-operator/files/pgo-configs/pool_passwd create mode 100644 ansible/roles/pgo-operator/files/pgo-configs/pvc-matchlabels.json create mode 100644 ansible/roles/pgo-operator/files/pgo-configs/pvc-storageclass.json create mode 100644 ansible/roles/pgo-operator/files/pgo-configs/pvc.json create mode 100644 ansible/roles/pgo-operator/files/pgo-configs/rmdata-job.json create mode 100644 ansible/roles/pgo-operator/files/pgo-configs/users.txt create mode 100644 ansible/roles/pgo-operator/files/service.json create mode 100644 ansible/roles/pgo-operator/tasks/certs.yml create mode 100644 ansible/roles/pgo-operator/tasks/cleanup.yml create mode 100644 ansible/roles/pgo-operator/tasks/crds.yml create mode 100644 ansible/roles/pgo-operator/tasks/deprecated.yml create mode 100644 ansible/roles/pgo-operator/tasks/kubernetes.yml create mode 100644 ansible/roles/pgo-operator/tasks/kubernetes_auth.yml create mode 100644 ansible/roles/pgo-operator/tasks/main.yml create mode 100644 ansible/roles/pgo-operator/tasks/openshift.yml create mode 100644 ansible/roles/pgo-operator/tasks/openshift_auth.yml create mode 100644 ansible/roles/pgo-operator/tasks/preflight.yml create mode 100644 ansible/roles/pgo-operator/tasks/ssh_keys.yml create mode 100644 ansible/roles/pgo-operator/templates/aws-s3-credentials.yaml.j2 create mode 100644 ansible/roles/pgo-operator/templates/cluster-rbac.yaml.j2 create mode 100644 ansible/roles/pgo-operator/templates/deployment.json.j2 create mode 100644 ansible/roles/pgo-operator/templates/pgo.yaml.j2 create mode 100644 ansible/roles/pgo-operator/templates/pgouser.j2 create mode 100644 ansible/roles/pgo-operator/templates/pgouser.local.j2 create mode 100644 ansible/roles/pgo-operator/templates/rbac.yaml.j2 create mode 100644 ansible/roles/pgo-operator/vars/main.yml create mode 100644 ansible/roles/pgo-operator/vars/openshift.yml create mode 100644 ansible/roles/pgo-preflight/tasks/check_kubernetes.yml create mode 100644 ansible/roles/pgo-preflight/tasks/check_openshift.yml create mode 100644 ansible/roles/pgo-preflight/tasks/main.yml create mode 100644 hugo/content/Installation/install-with-ansible/_index.md create mode 100644 hugo/content/Installation/install-with-ansible/installation/_index.md create mode 100644 hugo/content/Installation/install-with-ansible/installation/installing-ansible.md create mode 100644 hugo/content/Installation/install-with-ansible/installation/installing-metrics.md create mode 100644 hugo/content/Installation/install-with-ansible/installation/installing-operator.md create mode 100644 hugo/content/Installation/install-with-ansible/prereq/_index.md create mode 100644 hugo/content/Installation/install-with-ansible/prereq/prerequisites.md create mode 100644 hugo/content/Installation/install-with-ansible/uninstall/_index.md create mode 100644 hugo/content/Installation/install-with-ansible/uninstall/uninstalling-metrics.md create mode 100644 hugo/content/Installation/install-with-ansible/uninstall/uninstalling-operator.md diff --git a/.gitignore b/.gitignore index a48cf0de7a..a7cea663af 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ public +.DS_Store diff --git a/ansible/README.md b/ansible/README.md new file mode 100644 index 0000000000..a517b90591 --- /dev/null +++ b/ansible/README.md @@ -0,0 +1,15 @@ +# Crunchy Data PostgreSQL Operator Playbook + +

+ Mr. Crunchy +

+ +Latest Release: 4.0.0 + +## General + +This repository contains Ansible Roles for deploying the Crunchy PostgreSQL Operator +for Kubernetes and OpenShift. + +See the [official documentation for more information](https://crunchydata.github.io/postgres-operator-/stable/) +on installing Crunchy PostgreSQL Operator. diff --git a/ansible/ansible.cfg b/ansible/ansible.cfg new file mode 100644 index 0000000000..b23527277f --- /dev/null +++ b/ansible/ansible.cfg @@ -0,0 +1,5 @@ +[defaults] +retry_files_enabled = False + +[ssh_connection] +ssh_args = -o ControlMaster=no diff --git a/ansible/crunchy_logo.png b/ansible/crunchy_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..6322b4e10f627080ef89c55d686394887b5bf2b1 GIT binary patch literal 403323 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