diff --git a/ansible/inventories/production/hosts.ini b/ansible/inventories/production/hosts.ini index 12abbd5..c3ca97a 100644 --- a/ansible/inventories/production/hosts.ini +++ b/ansible/inventories/production/hosts.ini @@ -39,9 +39,10 @@ git.rockylinux.org ansible_host=10.100.1.113 [koji:children] kojihub kojid +mqtt [kojihub] -hub.boxbuild.rockylinux.org ansible_host=10.100.1.200 +koji.boxbuild.rockylinux.org ansible_host=10.100.1.200 [kojid] x86-01.boxbuild.rockylinux.org ansible_host=10.100.1.201 @@ -56,3 +57,6 @@ aarch64-06.boxbuild.rockylinux.org ansible_host=10.100.1.209 ppc64le-01.boxbuild.rockylinux.org ansible_host=10.100.1.210 ppc64le-02.boxbuild.rockylinux.org ansible_host=10.100.1.211 ppc64le-03.boxbuild.rockylinux.org ansible_host=10.100.1.212 + +[mqtt] +mqtt.boxbuild.rockylinux.org ansible_host=10.100.1.213 diff --git a/ansible/playbooks/adhoc-ipagetkeytab.yml b/ansible/playbooks/adhoc-ipagetkeytab.yml index 3863661..30fbe03 100644 --- a/ansible/playbooks/adhoc-ipagetkeytab.yml +++ b/ansible/playbooks/adhoc-ipagetkeytab.yml @@ -2,9 +2,10 @@ # This playbook is meant to be used with callable variables, like adhoc or AWX. # What: Pulls keytabs for a kerberos service # What is expected: -# -> ipaService, using this format: SVC/hostname.rockylinux.org@ROCKYLINUX.ORG -# -> ipaKeytabFullPath: The full path to the keytab. Example: /etc/gitlab/gitlab.keytab -# -> ipaServer: This needs to be one of the IPA servers +# -> ipa_service, using this format: SVC/hostname.rockylinux.org@ROCKYLINUX.ORG +# -> ipa_keytab_fullpath: The full path to the keytab. Example: /etc/gitlab/gitlab.keytab +# -> ipa_server: This needs to be one of the IPA servers +# -> ipa_owner: If applicable, the local account that will own this keytab (eg for Apache) - name: Pull keytab from IPA hosts: "{{ host }}" @@ -18,16 +19,27 @@ assert: that: - ipaadmin_password | mandatory - - ipaService | mandatory - - ipaKeytabFullPath | mandatory - - ipaServer | mandatory + - ipa_service | mandatory + - ipa_keytab_fullpath | mandatory + - ipa_server | mandatory success_msg: "Required variables provided" fail_msg: "We are missing required information" - name: "Pulling keytab" - command: "ipa-getkeytab -s {{ ipaServer }} -p {{ ipaService }} -k {{ ipaKeytabFullPath }}" + command: "ipa-getkeytab -s {{ ipa_server }} -p {{ ipa_service }} -k {{ ipa_keytab_fullpath }}" register: ipakeytab_result changed_when: - ipakeytab_result.rc == 0 tags: - keytab + + - name: "Set ownership if applicable" + file: + path: "{{ ipa_keytab_fullpath }}" + owner: "{{ ipa_owner }}" + group: "{{ ipa_owner }}" + mode: '0600' + state: file + when: ipa_owner + tags: + - keytab diff --git a/ansible/playbooks/adhoc-ipaservice.yml b/ansible/playbooks/adhoc-ipaservice.yml index 45af9a1..13ba128 100644 --- a/ansible/playbooks/adhoc-ipaservice.yml +++ b/ansible/playbooks/adhoc-ipaservice.yml @@ -14,13 +14,15 @@ assert: that: - ipaadmin_password | mandatory - - ipaService | mandatory + - ipa_service | mandatory success_msg: "Required variables provided" fail_msg: "We are missing required information" - name: "Creating Kerberos Service" freeipa.ansible_freeipa.ipaservice: ipaadmin_password: "{{ ipaadmin_password }}" - name: "{{ ipaService }}" + name: "{{ ipa_service }}" + skip_host_check: "{{ ipa_skip_host_check | default(false) }}" + force: "{{ ipa_force | default(false) }}" tags: - services diff --git a/ansible/playbooks/import-rockygroups.yml b/ansible/playbooks/import-rockygroups.yml index fdd9a95..46e790f 100644 --- a/ansible/playbooks/import-rockygroups.yml +++ b/ansible/playbooks/import-rockygroups.yml @@ -6,6 +6,7 @@ name: "{{ item.group }}" description: "{{ item.description }}" nonposix: false + user: "{{ item.user | default(none) }}" loop: "{{ ipagroups }}" tags: - groups diff --git a/ansible/playbooks/import-rockypwpolicy.yml b/ansible/playbooks/import-rockypwpolicy.yml new file mode 100644 index 0000000..01c675f --- /dev/null +++ b/ansible/playbooks/import-rockypwpolicy.yml @@ -0,0 +1,16 @@ +--- +# Creates the first set of groups for the IdM Infrastructure +- name: "Setting up password policies" + freeipa.ansible_freeipa.ipapwpolicy: + ipaadmin_password: "{{ ipaadmin_password }}" + name: "{{ item.group }}" + minlife: "{{ item.minlife | default(0) }}" + maxlife: "{{ item.maxlife | default(84) }}" + history: "{{ item.history | default(5) }}" + priority: "{{ item.priority | default(1) }}" + lockouttime: "{{ item.lockout | default(300) }}" + minlength: "{{ item.minlength | default(8) }}" + maxfile: "{{ item.maxfail | default(5) }}" + loop: "{{ ipapwpolicies }}" + tags: + - groups diff --git a/ansible/playbooks/init-rocky-ipa-internal-dns.yml b/ansible/playbooks/init-rocky-ipa-internal-dns.yml index ee77153..dba3d5d 100644 --- a/ansible/playbooks/init-rocky-ipa-internal-dns.yml +++ b/ansible/playbooks/init-rocky-ipa-internal-dns.yml @@ -7,6 +7,7 @@ vars_files: - vars/encpass.yml - vars/rdns.yml + - vars/fdns.yml tasks: - name: "Checking for user variables" @@ -21,3 +22,9 @@ ipaadmin_password: '{{ ipaadmin_password }}' name: '{{ item }}' with_items: '{{ rdns }}' + + - name: "Create Forward Domains" + freeipa.ansible_freeipa.ipadnszone: + ipaadmin_password: '{{ ipaadmin_password }}' + name: '{{ item }}' + with_items: '{{ fdns }}' diff --git a/ansible/playbooks/role-gitlab-ee.yml b/ansible/playbooks/role-gitlab-ee.yml index ff50ab9..e52b63c 100644 --- a/ansible/playbooks/role-gitlab-ee.yml +++ b/ansible/playbooks/role-gitlab-ee.yml @@ -28,6 +28,10 @@ state: present roles: + - role: geerlingguy.certbot + state: present + when: not gitlab_create_self_signed_cert + - role: geerlingguy.gitlab state: present diff --git a/ansible/playbooks/role-rocky-kojihub.yml b/ansible/playbooks/role-rocky-kojihub.yml new file mode 100644 index 0000000..fec3d07 --- /dev/null +++ b/ansible/playbooks/role-rocky-kojihub.yml @@ -0,0 +1,83 @@ +--- +# Stands up an ipsilon instance for simple SSO +- name: Configure koji hub and web server + hosts: kojihub + become: true + vars_files: + - vars/encpass.yml + - vars/kojihub.yml + + # This is to try to avoid the handler issue in pre/post tasks + handlers: + - import_tasks: handlers/main.yml + + pre_tasks: + - name: Check if ansible cannot be run here + stat: + path: /etc/no-ansible + register: no_ansible + + - name: Verify if we can run ansible + assert: + that: + - "not no_ansible.stat.exists" + msg: "/etc/no-ansible exists - skipping run on this node" + + # EPEL and PowerTools are required for ipsilon to function + # I also couldn't find an ansible built-in to do this + - name: Enable the PowerTools repository + ini_file: + dest: /etc/yum.repos.d/CentOS-Linux-PowerTools.repo + section: powertools + option: enabled + value: 1 + owner: root + group: root + mode: '0644' + + # The CentOS extras repos has epel-release provided + - name: Enable the EPEL repository + yum: + name: epel-release + state: present + tags: + - packages + + - name: Install rocky-tools copr + yum_repository: + name: copr:copr.fedorainfracloud.org:nalika:rockylinux-tool + description: Copr repo for rockylinux-tools owned by nalika + file: copr_repos + baseurl: https://download.copr.fedorainfracloud.org/results/nalika/rockylinux-tools/epel-8-$basearch/ + gpgcheck: true + gpgkey: https://download.copr.fedorainfracloud.org/results/nalika/rockylinux-tools/pubkey.gpg + enabled: true + + # Right now, we are not sure how or where we'll get our certificates. So we + # are presenting a choice by setting a variable, koji_internal_ca. There is a + # change that we will have to do internal certs for mqtt anyway. + # TODO: We need an MQTT role and pre_tasks for the keytabs for this role + roles: + - role: geerlingguy.certbot + state: present + when: not koji_internal_ca + + - role: rockylinux.ipagetcert + state: present + when: koji_internal_ca + + - role: geerlingguy.postgresql + state: present + when: koji_postgresql_vm + + - role: rockylinux.kojihub + state: present + + post_tasks: + - name: Touching run file that ansible has ran here + file: + path: /var/log/ansible.run + state: touch + mode: '0644' + owner: root + group: root diff --git a/ansible/playbooks/role-rocky-mqtt.yml b/ansible/playbooks/role-rocky-mqtt.yml new file mode 100644 index 0000000..bba8629 --- /dev/null +++ b/ansible/playbooks/role-rocky-mqtt.yml @@ -0,0 +1,60 @@ +--- +# Stands up an mqtt instance +- name: Configure mqtt + hosts: kojihub + become: true + vars_files: + - vars/encpass.yml + - vars/mqtt.yml + + # This is to try to avoid the handler issue in pre/post tasks + handlers: + - import_tasks: handlers/main.yml + + pre_tasks: + - name: Check if ansible cannot be run here + stat: + path: /etc/no-ansible + register: no_ansible + + - name: Verify if we can run ansible + assert: + that: + - "not no_ansible.stat.exists" + msg: "/etc/no-ansible exists - skipping run on this node" + + # EPEL and PowerTools are required for ipsilon to function + # I also couldn't find an ansible built-in to do this + - name: Enable the PowerTools repository + ini_file: + dest: /etc/yum.repos.d/CentOS-Linux-PowerTools.repo + section: powertools + option: enabled + value: 1 + owner: root + group: root + mode: '0644' + + # The CentOS extras repos has epel-release provided + - name: Enable the EPEL repository + yum: + name: epel-release + state: present + tags: + - packages + + roles: + - role: rockylinux.ipagetcert + state: present + + - role: rockylinux.mqtt + state: present + + post_tasks: + - name: Touching run file that ansible has ran here + file: + path: /var/log/ansible.run + state: touch + mode: '0644' + owner: root + group: root diff --git a/ansible/playbooks/templates/etc/nginx/conf.d/omnibus.conf.j2 b/ansible/playbooks/templates/etc/nginx/conf.d/omnibus.conf.j2 index 9bf023c..a9fbea8 100644 --- a/ansible/playbooks/templates/etc/nginx/conf.d/omnibus.conf.j2 +++ b/ansible/playbooks/templates/etc/nginx/conf.d/omnibus.conf.j2 @@ -31,12 +31,12 @@ server { ## Strong SSL Security ## https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html & https://cipherli.st/ ssl on; - ssl_certificate /etc/nginx/ssl/gitlab.crt; - ssl_certificate_key /etc/nginx/ssl/gitlab.key; + ssl_certificate {{ gitlab_ssl_cert }}; + ssl_certificate_key {{ gitlab_ssl_key }}; # GitLab needs backwards compatible ciphers to retain compatibility with Java IDEs ssl_ciphers "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4"; - ssl_protocols TLSv1 TLSv1.1 TLSv1.2; + ssl_protocols TLSv1.1 TLSv1.2; ssl_prefer_server_ciphers on; ssl_session_cache shared:SSL:10m; ssl_session_timeout 5m; diff --git a/ansible/playbooks/vars/encpass.yml b/ansible/playbooks/vars/encpass.yml index b4e2d15..efa8dc7 100644 --- a/ansible/playbooks/vars/encpass.yml +++ b/ansible/playbooks/vars/encpass.yml @@ -13,3 +13,6 @@ ipadm_password: !vault | ipsilon_db_password: !vault | $ANSIBLE_VAULT;1.1;AES256 REDACTED +koji_db_pass: !vault | + $ANSIBLE_VAULT;1.1;AES256 + REDACTED diff --git a/ansible/playbooks/vars/fdns.yml b/ansible/playbooks/vars/fdns.yml new file mode 100644 index 0000000..88cb46c --- /dev/null +++ b/ansible/playbooks/vars/fdns.yml @@ -0,0 +1,3 @@ +--- +fdns: + - boxbuild.rockylinux.org. diff --git a/ansible/playbooks/vars/gitlab.yml b/ansible/playbooks/vars/gitlab.yml index e489443..bfa66de 100644 --- a/ansible/playbooks/vars/gitlab.yml +++ b/ansible/playbooks/vars/gitlab.yml @@ -16,6 +16,8 @@ gitlab_create_self_signed_cert: "true" gitlab_self_signed_cert_subj: "/C=US/ST=Missouri/L=Saint Louis/O=IT/CN={{ gitlab_domain }}" gitlab_ssl_certificate: "/etc/gitlab/ssl/{{ gitlab_domain }}.crt" gitlab_ssl_certificate_key: "/etc/gitlab/ssl/{{ gitlab_domain }}.key" +gitlab_ssl_cert: "/etc/nginx/ssl/{{ gitlab_domain }}.crt" +gitlab_ssl_key: "/etc/nginx/ssl/{{ gitlab_domain }}.key" # LDAP Configuration gitlab_ldap_enabled: "true" diff --git a/ansible/playbooks/vars/groups.yml b/ansible/playbooks/vars/groups.yml index e69d6c5..e5b37de 100644 --- a/ansible/playbooks/vars/groups.yml +++ b/ansible/playbooks/vars/groups.yml @@ -2,8 +2,18 @@ ipagroups: - group: infrastructure description: Infrastructure Team + user: + - label + - neil + - rlh + - rfelsburg + - tg + - bagner - group: operations description: Operations Team + user: + - rlh + - rfelsburg - group: development description: Development Team - group: qa @@ -12,5 +22,29 @@ ipagroups: description: Marketing - group: rockyadm description: Rocky Linux Administrators - Only Admin Accounts + user: + - label2 + - gmk2 + - brian2 + - hbjy2 + - jorp2 + - neil2 + - rlh2 + - rfelsburg2 + - tg2 + - bagner2 - group: gitadm description: Rocky Linux GitLab Admins + user: + - label + - neil + - rlh + - rfelsburg + - tg + - hbjy + - group: services + description: Rocky Linux Service Accounts + user: + - hostman + - kerbman + - rockykoji diff --git a/ansible/playbooks/vars/kojihub.yml b/ansible/playbooks/vars/kojihub.yml new file mode 100644 index 0000000..ec3cdb2 --- /dev/null +++ b/ansible/playbooks/vars/kojihub.yml @@ -0,0 +1,100 @@ +--- +# koji hub settings + +# Use an internal CA (IPA) +koji_internal_ca: true + +# Use postgresql on this machine rather than managed service +koji_postgresql_vm: true + +# Database settings +koji_db_name: koji +koji_db_user: koji +# This will need to change when koji_postgresql_vm is false +koji_db_host: "{{ ansible_fqdn }}" + +koji_web_url: "https://{{ ansible_fqdn }}/koji" +koji_hub_url: "https://{{ ansible_fqdn }}/kojihub" +koji_files_url: "https://{{ ansible_fqdn }}/kojifiles" + +# The IPA internal CA is combined with the others +koji_web_cacert: /etc/pki/tls/certs/ca-bundle.crt +koji_web_tls_cert: "/etc/pki/tls/certs/{{ ansible_fqdn }}.crt" +koji_web_tls_key: "/etc/pki/tls/private/{{ ansible_fqdn }}.key" + +# NFS? We need a place. +koji_nfs: false +koji_mount: /mnt/koji +koji_nfs_path: nfs.rockylinux.org:/export/koji + +# Koji Admin Settings +koji_admin_client: true +koji_admin_user: rockykoji +koji_admin_principal: rockykoji@ROCKYLINUX.ORG +koji_admin_localuser: true +koji_admin_localuser_name: koji + +# Hub Settings +koji_hub_principal: "HTTP/{{ ansible_fqdn }}@ROCKYLINUX.ORG" +koji_hub_proxy_principals: koji/kojiweb@ROCKYLINUX.ORG +koji_hub_keytab: /etc/koji.keytab +koji_hub_principal_format: compile/%s@ROCKYLINUX.ORG +# This should be sufficient even for LE +koji_hub_ca: "{{ koji_web_cacert }}" + +# Koji FAS Syncing +# This isn't implemented yet in the role +koji_fas_sync: false +koji_fas_url: https://accounts.rockylinux.org + +# Not implemented yet +koji_hub_plugin_mqtt_host: mqtt.rockylinux.org +koji_hub_plugin_mqtt_topic: koji +koji_hub_plugin_mqtt_ca: "{{ koji_hub_ca }}" +koji_hub_plugin_mqtt_tls_cert: /etc/pki/tls/certs/mqtt.pem +koji_hub_plugin_mqtt_tls_key: /etc/pki/tls/certs/mqtt.key +koji_hub_plugin_mqtt_excluded_tags: + - testing-tag + +# IPA Certs if Required +ipa_getcert_requested_hostnames: + - name: "{{ ansible_fqdn }}" + owner: apache + key_location: "{{ koji_web_tls_key }}" + cert_location: "{{ koji_web_tls_cert }}" + postcmd: "/bin/systemctl reload httpd" + +# postgresql vars +postgresql_restarted_state: "restarted" +postgresql_python_library: python3-psycopg2 +postgresql_user: postgres +postgresql_group: postgres +postgresql_hba_entries: + - type: local + database: koji + user: koji + auth_method: trust + - type: local + database: all + user: postgres + auth_method: peer + - type: host + database: koji + user: koji + address: '10.100.1.0/24' + auth_method: md5 + +postgresql_databases: + - name: "{{ koji_db_name }}" + owner: "{{ koji_db_user }}" + +postgresql_users: + - name: "{{ koji_db_user }}" + password: "{{ koji_db_pass }}" + role_attr_flags: "NOCREATEDB,NOSUPERUSER,NOCREATEROLE" + db: "{{ koji_db_name }}" + state: present + +postgresql_global_config_options: + - option: listen_addresses + value: '*' diff --git a/ansible/playbooks/vars/mqtt.yml b/ansible/playbooks/vars/mqtt.yml new file mode 100644 index 0000000..48a8ffb --- /dev/null +++ b/ansible/playbooks/vars/mqtt.yml @@ -0,0 +1,5 @@ +--- +# mqtt settings +mqtt_tls_ca_cert: "/etc/pki/tls/certs/ca-bundle.crt" +mqtt_tls_cert: "/etc/pki/tls/certs/{{ ansible_fqdn }}.crt" +mqtt_tls_key: "/etc/pki/tls/private/{{ ansible_fqdn }}.key" diff --git a/ansible/playbooks/vars/svcusers.yml b/ansible/playbooks/vars/svcusers.yml index 8dfce8b..ccef80d 100644 --- a/ansible/playbooks/vars/svcusers.yml +++ b/ansible/playbooks/vars/svcusers.yml @@ -3,14 +3,21 @@ svcusers: - name: hostman first: Host last: Manager - email: hostman@rockylinux.org + email: infrastructure@rockylinux.org password: ThisIsNotMyPassword1! title: System Account - Host Manager loginshell: /sbin/nologin - name: kerbman first: Kerberos last: Manager - email: kerbman@rockylinux.org + email: infrastructure@rockylinux.org password: ThisIsNotMyPassword1! title: System Account - Kerberos Key Manager loginshell: /sbin/nologin + - name: rockykoji + first: Koji + last: Manager + email: infrastructure@rockylinux.org + password: ThisIsNotMyPassword1! + title: System Account - Koji Manager + loginshell: /sbin/nologin diff --git a/ansible/roles/requirements.yml b/ansible/roles/requirements.yml index 6745378..b72a768 100644 --- a/ansible/roles/requirements.yml +++ b/ansible/roles/requirements.yml @@ -5,10 +5,20 @@ roles: # monitoring - name: cloudalchemy.node-exporter - name: cloudalchemy.prometheus + - name: geerlingguy.gitlab + - name: geerlingguy.postgresql + - name: rockylinux.ipagetcert + src: https://github.com/rocky-linux/ansible-role-ipa-getcert + version: main - name: rockylinux.ipsilon src: https://github.com/rocky-linux/ansible-role-ipsilon version: main - - name: geerlingguy.gitlab + - name: rockylinux.kojihub + src: https://github.com/rocky-linux/ansible-role-kojihub + version: main + - name: rockylinux.mqtt + src: https://github.com/rocky-linux/ansible-role-mqtt + version: main collections: # freeipa