diff --git a/automation/README.md b/automation/README.md new file mode 100644 index 000000000..d631e1527 --- /dev/null +++ b/automation/README.md @@ -0,0 +1,45 @@ +Overview +-------- + +This is a ansible based project to deploy all eda-server related components. + +Pre-requisites +-------------- + +Minikube - https://minikube.sigs.k8s.io/docs ( `minikube addons enable ingress`, `minikube addons enable storage-provisioner` and `minikube addons enable default-storageclass` ) + +Red Hat OpenShift Local - https://developers.redhat.com/products/openshift-local/overview + +Ansible - https://github.com/ansible/ansible + +Kubernetes Collection for Ansible - `ansible-galaxy collection install kubernetes.core` + + +Usage +-------------- + +Make sure that your Minikube or Openshift Local is running. + +After that, review the variables and make any necessary customizations. This can be done in the file: + +```bash +group_vars/all/vars.yml + ``` + +The following variables can be customized to determine whether a specific action is executed or not. + +**env_type**: This variable supports `"minikube"` or `"openshift"` as the execution target. + +**eda_deploy_operator**: This variable must be set to `"true"` for the eda-server-operator to be installed. + +**eda_deploy_server**: This variable must be set to `"true"` for eda-server to be installed. At this moment, this installation still relies on the eda-server-operator, as everything is based on the "eda" crd. + +**awx_deploy_operator**: This variable must be set to `"true"` for the awx-server-operator to be installed. + +**awx_deploy_server**: This variable must be set to `"true"` for awx-server to be installed. At this moment, this installation still relies on the awx-server-operator, as everything is based on the "awx" crd. + +To run, simply be in the same directory as the `playbook.yaml` file and execute the command: `ansible-playbook playbook.yaml` + +At the end of the execution, you should have all components installed in the namespace defined in the variable `eda_namespace` + +In openshift-local (crc) you can access the UI at `eda-aap-eda.apps-crc.testing` and in minikube at `eda.local` \ No newline at end of file diff --git a/automation/ansible.cfg b/automation/ansible.cfg new file mode 100644 index 000000000..73e8fc572 --- /dev/null +++ b/automation/ansible.cfg @@ -0,0 +1,4 @@ +[defaults] +host_key_checking = False +retry_files_enabled = False +callback_whitelist = profile_tasks \ No newline at end of file diff --git a/automation/group_vars/all/vars.yaml b/automation/group_vars/all/vars.yaml new file mode 100644 index 000000000..6f8ee8f7c --- /dev/null +++ b/automation/group_vars/all/vars.yaml @@ -0,0 +1,96 @@ +--- +ansible_python_interpreter: /usr/bin/env python + +env_type: minikube #openshift +eda_deploy_operator: "true" +eda_deploy_server: "true" + +eda_namespace: aap-eda + +eda_operator: + api_version: kustomize.config.k8s.io/v1beta1 + namespace: aap-eda + disable_name_suffix_hash: true + secret_generator_name: redhat-operators-pull-secret + operator_literal: eda + resource_url: github.com/ansible/eda-server-operator/config/default?ref=1.0.2 + image_name: quay.io/ansible/eda-server-operator + image_new_tag: 1.0.2 + +eda_operator_files_path: roles/eda-deploy-operator/files +eda_server_files_path: roles/eda-deploy-server/files + +eda_server: + pvc_name: eda-postgres-15-volume + access_modes: ReadWriteOnce + storage_request: 500Mi + namespace: aap-eda + admin_user: admin + admin_password_secret: eda-admin-password + automation_server_url: https://awx.local + automation_server_ssl_verify: "no" + image: quay.io/ansible/eda-server + image_version: sha-f376c46 + image_web: quay.io/ansible/eda-ui + image_web_version: latest + redis_image: + redis_image_version: + postgres_image: quay.io/sclorg/postgresql-15-c9s + postgres_image_version: latest + api: + replicas: 1 + ui: + replicas: 1 + worker: + replicas: 2 + redis: + replicas: 1 + database: + database_secret: eda-database-configuration + storage_requirements: + requests: + storage: 3Gi + resource_requirements: + requests: {} + +eda_server_kustomization: + eda_database_configuration_host: eda-postgres-15 + eda_database_configuration_port: 5432 + eda_database_configuration_database: eda + eda_database_configuration_username: eda + eda_database_configuration_password: testpass + eda_database_configuration_type: managed + eda_admin_password: testpass + +# AWX + +aws_deploy_operator: "false" +aws_deploy_server: "false" +awx_operator_files_path: roles/awx-deploy-operator/files +awx_server_files_path: roles/awx-deploy-server/files +awx_namespace: aap-awx + +awx_operator: + disableNameSuffixHash: true + secretName: "redhat-operators-pull-secret" + operatorLiteral: "operator=awx" + awxOperatorConfigURL: "github.com/ansible/awx-operator/config/default?ref=2.16.0" + operatorImageName: "quay.io/ansible/awx-operator" + operatorImageTag: "2.16.0" + +awx_server: + pvc_name: awx-postgres-15-volume + access_modes: ReadWriteOnce + storage_request: 3Gi + admin_user: admin + admin_password_secret: awx-admin-password + +awx_server_kustomization: + awx_database_configuration_host: awx-postgres-15 + awx_database_configuration_port: 5432 + awx_database_configuration_database: awx + awx_database_configuration_username: awx + awx_database_configuration_password: testpass + awx_database_configuration_type: managed + awx_admin_password: testpass + diff --git a/automation/hosts b/automation/hosts new file mode 100644 index 000000000..e2ff33d34 --- /dev/null +++ b/automation/hosts @@ -0,0 +1,2 @@ +[all] +localhost \ No newline at end of file diff --git a/automation/playbook.yaml b/automation/playbook.yaml new file mode 100644 index 000000000..80a392c5a --- /dev/null +++ b/automation/playbook.yaml @@ -0,0 +1,14 @@ +- hosts: localhost + roles: + + - name: eda-deploy-operator + when: eda_deploy_operator == "true" + + - name: eda-deploy-server + when: eda_deploy_server == "true" + + - name: awx-deploy-operator + when: aws_deploy_operator == "true" + + - name: awx-deploy-server + when: aws_deploy_server == "true" \ No newline at end of file diff --git a/automation/roles/awx-deploy-operator/files/.gitkeep b/automation/roles/awx-deploy-operator/files/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/automation/roles/awx-deploy-operator/tasks/main.yaml b/automation/roles/awx-deploy-operator/tasks/main.yaml new file mode 100644 index 000000000..3e4f87868 --- /dev/null +++ b/automation/roles/awx-deploy-operator/tasks/main.yaml @@ -0,0 +1,35 @@ +--- +- name: Check {{ env_type }} connection + block: + - k8s_info: + api_version: v1 + kind: Pod + namespace: default + name: ansible-check-pod + kubeconfig: "{{ lookup('env', 'KUBECONFIG') }}" + register: k8s_info_result + rescue: + - fail: + msg: "Failed to connect to Kubernetes cluster. Please check your configuration and try again." + always: + - debug: + var: k8s_info_result + +- name: Create {{ awx_namespace }} namespace + k8s: + definition: + apiVersion: v1 + kind: Namespace + metadata: + name: "{{ awx_namespace }}" + when: k8s_info_result is succeeded + +- name: Generate AWX Operator kustomization file + template: + src: kustomization-awx-operator.yaml.j2 + dest: "{{ awx_operator_files_path }}/kustomization.yaml" + +- name: Apply AWX Operator kustomization file + k8s: + definition: "{{ lookup('pipe', 'kustomize build {{ awx_operator_files_path }}') }}" + state: present \ No newline at end of file diff --git a/automation/roles/awx-deploy-operator/templates/kustomization-awx-operator.yaml.j2 b/automation/roles/awx-deploy-operator/templates/kustomization-awx-operator.yaml.j2 new file mode 100644 index 000000000..2778dde8f --- /dev/null +++ b/automation/roles/awx-deploy-operator/templates/kustomization-awx-operator.yaml.j2 @@ -0,0 +1,18 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +namespace: {{ awx_namespace }} + +generatorOptions: + disableNameSuffixHash: {{ awx_operator.disableNameSuffixHash | default('false') }} + +secretGenerator: + - name: {{ awx_operator.secretName }} + literals: + - operator={{ awx_operator.operatorLiteral }} + +resources: + - {{ awx_operator.awxOperatorConfigURL }} + +images: + - name: {{ awx_operator.operatorImageName }} + newTag: {{ awx_operator.operatorImageTag }} \ No newline at end of file diff --git a/automation/roles/awx-deploy-server/files/.gitkeep b/automation/roles/awx-deploy-server/files/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/automation/roles/awx-deploy-server/tasks/main.yaml b/automation/roles/awx-deploy-server/tasks/main.yaml new file mode 100644 index 000000000..75ec22112 --- /dev/null +++ b/automation/roles/awx-deploy-server/tasks/main.yaml @@ -0,0 +1,80 @@ +--- +- name: Check {{ env_type }} connection + block: + - k8s_info: + api_version: v1 + kind: Pod + namespace: default + name: ansible-check-pod + kubeconfig: "{{ lookup('env', 'KUBECONFIG') }}" + register: k8s_info_result + rescue: + - fail: + msg: "Failed to connect to Kubernetes cluster. Please check your configuration and try again." + always: + - debug: + var: k8s_info_result + +- name: Check if {{ awx_namespace }} namespace exists + k8s_info: + kind: Namespace + name: "{{ awx_namespace }}" + kubeconfig: "{{ lookup('env', 'KUBECONFIG') }}" + register: namespace_info + failed_when: namespace_info.resources|length == 0 + +- name: Define the AWX Host + set_fact: + awx_host: "{{ 'awx.local' if env_type == 'minikube' else 'awx-aap-awx.apps-crc.testing' }}" + +- name: Generate private key + command: "openssl genpkey -algorithm RSA -out tls.key" + args: + chdir: "{{ awx_server_files_path }}" + +- name: Generate certificate signing request (CSR) + command: "openssl req -new -key tls.key -out csr.pem -subj '/CN={{ awx_host }}/O={{ awx_host }}' -addext 'subjectAltName=DNS:{{ awx_host }}'" + args: + chdir: "{{ awx_server_files_path }}" + +- name: Generate signed certificate + command: "openssl x509 -req -in csr.pem -signkey tls.key -out tls.crt -days 365" + args: + chdir: "{{ awx_server_files_path }}" + +- name: Remove temporary certificate signing request (CSR) + file: + path: "{{ awx_server_files_path }}/csr.pem" + state: absent + +- name: Define Ingress type + set_fact: + ingress_type: "{{ 'ingress' if env_type == 'minikube' else 'Route' }}" + +- name: Define the TLS termination Mechanism + set_fact: + tls_termination_mechanism: "{{ '' if env_type == 'minikube' else 'Edge' }}" + +- name: Define the PostgreSQL storage class + set_fact: + postgres_storage_class: "{{ 'standard' if env_type == 'minikube' else 'crc-csi-hostpath-provisioner' }}" + +- name: Generate AWX Server pvc file + template: + src: awx-server-pvc.yaml.j2 + dest: "{{ awx_server_files_path }}/awx-server-pvc.yaml" + +- name: Generate AWX Server file + template: + src: awx-server.yaml.j2 + dest: "{{ awx_server_files_path }}/awx-server.yaml" + +- name: Generate AWX Server kustomization file + template: + src: awx-server-kustomization.yaml.j2 + dest: "{{ awx_server_files_path }}/kustomization.yaml" + +- name: Apply AWX Server kustomization file + k8s: + definition: "{{ lookup('pipe', 'kustomize build {{ awx_server_files_path }}') }}" + state: present \ No newline at end of file diff --git a/automation/roles/awx-deploy-server/templates/awx-server-kustomization.yaml.j2 b/automation/roles/awx-deploy-server/templates/awx-server-kustomization.yaml.j2 new file mode 100644 index 000000000..cf0883a8d --- /dev/null +++ b/automation/roles/awx-deploy-server/templates/awx-server-kustomization.yaml.j2 @@ -0,0 +1,33 @@ +--- +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +namespace: {{ awx_namespace }} + +generatorOptions: + disableNameSuffixHash: true + +secretGenerator: + - name: awx-secret-tls + files: + - tls.crt + - tls.key + +secretGenerator: + - name: awx-database-configuration + type: Opaque + literals: + - host={{ awx_server_kustomization.awx_database_configuration_host }} + - port={{ awx_server_kustomization.awx_database_configuration_port }} + - database={{ awx_server_kustomization.awx_database_configuration_database }} + - username={{ awx_server_kustomization.awx_database_configuration_username }} + - password={{ awx_server_kustomization.awx_database_configuration_password }} + - type=managed + + - name: awx-admin-password + type: Opaque + literals: + - password={{ awx_server_kustomization.awx_admin_password }} + +resources: + - awx-server-pvc.yaml + - awx-server.yaml \ No newline at end of file diff --git a/automation/roles/awx-deploy-server/templates/awx-server-pvc.yaml.j2 b/automation/roles/awx-deploy-server/templates/awx-server-pvc.yaml.j2 new file mode 100644 index 000000000..7c3fac797 --- /dev/null +++ b/automation/roles/awx-deploy-server/templates/awx-server-pvc.yaml.j2 @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ awx_server.pvc_name }} + namespace: {{ awx_namespace }} +spec: + accessModes: + - "{{ awx_server.access_modes }}" + resources: + requests: + storage: {{ awx_server.storage_request }} +status: {} \ No newline at end of file diff --git a/automation/roles/awx-deploy-server/templates/awx-server.yaml.j2 b/automation/roles/awx-deploy-server/templates/awx-server.yaml.j2 new file mode 100644 index 000000000..2b1d2b45a --- /dev/null +++ b/automation/roles/awx-deploy-server/templates/awx-server.yaml.j2 @@ -0,0 +1,35 @@ +apiVersion: awx.ansible.com/v1beta1 +kind: AWX +metadata: + name: awx +spec: + admin_user: {{ awx_server.admin_user }} + admin_password_secret: {{ awx_server.admin_password_secret }} + + route_tls_termination_mechanism: {{ tls_termination_mechanism }} + ingress_tls_secret: awx-secret-tls + ingress_type: {{ ingress_type }} + hostname: {{ awx_host }} + + postgres_configuration_secret: awx-postgres-configuration + + postgres_storage_requirements: + requests: + storage: 1Gi + + #projects_persistence: true + #projects_existing_claim: awx-postgres-15-volume + + web_replicas: 1 + task_replicas: 1 + + postgres_init_container_resource_requirements: {} + postgres_resource_requirements: {} + web_resource_requirements: {} + task_resource_requirements: {} + ee_resource_requirements: {} + init_container_resource_requirements: {} + + # Uncomment to reveal "censored" logs + #no_log: false + diff --git a/automation/roles/eda-deploy-operator/files/.gitkeep b/automation/roles/eda-deploy-operator/files/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/automation/roles/eda-deploy-operator/tasks/main.yaml b/automation/roles/eda-deploy-operator/tasks/main.yaml new file mode 100644 index 000000000..b11210f24 --- /dev/null +++ b/automation/roles/eda-deploy-operator/tasks/main.yaml @@ -0,0 +1,35 @@ +--- +- name: Check {{ env_type }} connection + block: + - k8s_info: + api_version: v1 + kind: Pod + namespace: default + name: ansible-check-pod + kubeconfig: "{{ lookup('env', 'KUBECONFIG') }}" + register: k8s_info_result + rescue: + - fail: + msg: "Failed to connect to Kubernetes cluster. Please check your configuration and try again." + always: + - debug: + var: k8s_info_result + +- name: Create {{ eda_namespace }} namespace + k8s: + definition: + apiVersion: v1 + kind: Namespace + metadata: + name: "{{ eda_namespace }}" + when: k8s_info_result is succeeded + +- name: Generate EDA Operator kustomization file + template: + src: kustomization-eda-operator.yaml.j2 + dest: "{{ eda_operator_files_path }}/kustomization.yaml" + +- name: Apply EDA Operator kustomization file + k8s: + definition: "{{ lookup('pipe', 'kustomize build {{ eda_operator_files_path }}') }}" + state: present \ No newline at end of file diff --git a/automation/roles/eda-deploy-operator/templates/kustomization-eda-operator.yaml.j2 b/automation/roles/eda-deploy-operator/templates/kustomization-eda-operator.yaml.j2 new file mode 100644 index 000000000..e472be10e --- /dev/null +++ b/automation/roles/eda-deploy-operator/templates/kustomization-eda-operator.yaml.j2 @@ -0,0 +1,18 @@ +apiVersion: {{ eda_operator.api_version }} +kind: Kustomization +namespace: {{ eda_operator.namespace }} + +generatorOptions: + disableNameSuffixHash: {{ eda_operator.disable_name_suffix_hash }} + +secretGenerator: + - name: {{ eda_operator.secret_generator_name }} + literals: + - operator={{ eda_operator.operator_literal }} + +resources: + - {{ eda_operator.resource_url }} + +images: + - name: {{ eda_operator.image_name }} + newTag: {{ eda_operator.image_new_tag }} diff --git a/automation/roles/eda-deploy-server/files/.gitkeep b/automation/roles/eda-deploy-server/files/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/automation/roles/eda-deploy-server/tasks/main.yaml b/automation/roles/eda-deploy-server/tasks/main.yaml new file mode 100644 index 000000000..9a0373839 --- /dev/null +++ b/automation/roles/eda-deploy-server/tasks/main.yaml @@ -0,0 +1,80 @@ +--- +- name: Check {{ env_type }} connection + block: + - k8s_info: + api_version: v1 + kind: Pod + namespace: default + name: ansible-check-pod + kubeconfig: "{{ lookup('env', 'KUBECONFIG') }}" + register: k8s_info_result + rescue: + - fail: + msg: "Failed to connect to Kubernetes cluster. Please check your configuration and try again." + always: + - debug: + var: k8s_info_result + +- name: Check if {{ eda_namespace }} namespace exists + k8s_info: + kind: Namespace + name: "{{ eda_namespace }}" + kubeconfig: "{{ lookup('env', 'KUBECONFIG') }}" + register: namespace_info + failed_when: namespace_info.resources|length == 0 + +- name: Define the EDA Host + set_fact: + eda_host: "{{ 'eda.local' if env_type == 'minikube' else 'eda-aap-eda.apps-crc.testing' }}" + +- name: Generate private key + command: "openssl genpkey -algorithm RSA -out tls.key" + args: + chdir: "{{ eda_server_files_path }}" + +- name: Generate certificate signing request (CSR) + command: "openssl req -new -key tls.key -out csr.pem -subj '/CN={{ eda_host }}/O={{ eda_host }}' -addext 'subjectAltName=DNS:{{ eda_host }}'" + args: + chdir: "{{ eda_server_files_path }}" + +- name: Generate signed certificate + command: "openssl x509 -req -in csr.pem -signkey tls.key -out tls.crt -days 365" + args: + chdir: "{{ eda_server_files_path }}" + +- name: Remove temporary certificate signing request (CSR) + file: + path: "{{ eda_server_files_path }}/csr.pem" + state: absent + +- name: Define Ingress type + set_fact: + ingress_type: "{{ 'ingress' if env_type == 'minikube' else 'Route' }}" + +- name: Define the TLS termination Mechanism + set_fact: + tls_termination_mechanism: "{{ '' if env_type == 'minikube' else 'Edge' }}" + +- name: Define the PostgreSQL storage class + set_fact: + postgres_storage_class: "{{ 'standard' if env_type == 'minikube' else 'crc-csi-hostpath-provisioner' }}" + +- name: Generate EDA Server pvc file + template: + src: eda-server-pvc.yaml.j2 + dest: "{{ eda_server_files_path }}/eda-server-pvc.yaml" + +- name: Generate EDA Server file + template: + src: eda-server.yaml.j2 + dest: "{{ eda_server_files_path }}/eda-server.yaml" + +- name: Generate EDA Server kustomization file + template: + src: eda-server-kustomization.yaml.j2 + dest: "{{ eda_server_files_path }}/kustomization.yaml" + +- name: Apply EDA Server kustomization file + k8s: + definition: "{{ lookup('pipe', 'kustomize build {{ eda_server_files_path }}') }}" + state: present \ No newline at end of file diff --git a/automation/roles/eda-deploy-server/templates/eda-server-kustomization.yaml.j2 b/automation/roles/eda-deploy-server/templates/eda-server-kustomization.yaml.j2 new file mode 100644 index 000000000..75dc7ff9c --- /dev/null +++ b/automation/roles/eda-deploy-server/templates/eda-server-kustomization.yaml.j2 @@ -0,0 +1,33 @@ +--- +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +namespace: {{ eda_namespace }} + +generatorOptions: + disableNameSuffixHash: true + +secretGenerator: + - name: eda-secret-tls + files: + - tls.crt + - tls.key + +secretGenerator: + - name: eda-database-configuration + type: Opaque + literals: + - host={{ eda_server_kustomization.eda_database_configuration_host }} + - port={{ eda_server_kustomization.eda_database_configuration_port }} + - database={{ eda_server_kustomization.eda_database_configuration_database }} + - username={{ eda_server_kustomization.eda_database_configuration_username }} + - password={{ eda_server_kustomization.eda_database_configuration_password }} + - type=managed + + - name: eda-admin-password + type: Opaque + literals: + - password={{ eda_server_kustomization.eda_admin_password }} + +resources: + - eda-server-pvc.yaml + - eda-server.yaml diff --git a/automation/roles/eda-deploy-server/templates/eda-server-pvc.yaml.j2 b/automation/roles/eda-deploy-server/templates/eda-server-pvc.yaml.j2 new file mode 100644 index 000000000..d2a84ccf5 --- /dev/null +++ b/automation/roles/eda-deploy-server/templates/eda-server-pvc.yaml.j2 @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ eda_server.pvc_name }} + namespace: {{ eda_server.namespace }} +spec: + accessModes: + - "{{ eda_server.access_modes }}" + resources: + requests: + storage: {{ eda_server.storage_request }} +status: {} \ No newline at end of file diff --git a/automation/roles/eda-deploy-server/templates/eda-server.yaml.j2 b/automation/roles/eda-deploy-server/templates/eda-server.yaml.j2 new file mode 100644 index 000000000..ab55a7406 --- /dev/null +++ b/automation/roles/eda-deploy-server/templates/eda-server.yaml.j2 @@ -0,0 +1,49 @@ +apiVersion: eda.ansible.com/v1alpha1 +kind: EDA +metadata: + name: eda +spec: + admin_user: {{ eda_server.admin_user }} + admin_password_secret: {{ eda_server.admin_password_secret }} + + route_tls_termination_mechanism: {{ tls_termination_mechanism }} + ingress_tls_secret: eda-secret-tls + ingress_type: {{ ingress_type }} + hostname: {{ eda_host }} + + automation_server_url: {{ eda_server.automation_server_url }} + automation_server_ssl_verify: {{ eda_server.automation_server_ssl_verify }} + + image: {{ eda_server.image }} + image_version: {{ eda_server.image_version }} + + image_web: {{ eda_server.image_web }} + image_web_version: {{ eda_server.image_web_version }} + + postgres_image: {{ eda_server.postgres_image }} + postgres_image_version: {{ eda_server.postgres_image_version }} + + api: + replicas: {{ eda_server.api.replicas }} + resource_requirements: + requests: {} + ui: + replicas: {{ eda_server.ui.replicas }} + resource_requirements: + requests: {} + worker: + replicas: {{ eda_server.worker.replicas }} + resource_requirements: + requests: {} + redis: + replicas: {{ eda_server.redis.replicas }} + resource_requirements: + requests: {} + database: + database_secret: {{ eda_server.database.database_secret }} + postgres_storage_class: {{ postgres_storage_class }} + storage_requirements: + requests: + storage: {{ eda_server.database.storage_requirements.requests.storage }} + resource_requirements: + requests: {} diff --git a/automation/roles/requirements.yaml b/automation/roles/requirements.yaml new file mode 100644 index 000000000..8bbfc3855 --- /dev/null +++ b/automation/roles/requirements.yaml @@ -0,0 +1,4 @@ +--- +collections: + - name: kubernetes.core + version: 3.0.0 \ No newline at end of file