From 80cf4f9a51c2cde1b9f5286f9badfb8d74ddd109 Mon Sep 17 00:00:00 2001 From: aaron Date: Tue, 24 Aug 2021 12:16:11 +0200 Subject: [PATCH] add gitlab role --- README.md | 62 +++++++++++++++++ defaults/main.yml | 104 +++++++++++++++++++++++++++++ handlers/main.yml | 13 ++++ tasks/configure.yml | 43 ++++++++++++ tasks/install.yml | 32 +++++++++ tasks/main.yml | 19 ++++++ templates/Gitlab.gitlab-license.j2 | 1 + templates/gitlab-secrets.json.j2 | 51 ++++++++++++++ templates/gitlab.rb.j2 | 75 +++++++++++++++++++++ templates/gitlab.repo.j2 | 10 +++ vars/gitlab_pkg_dependencies.yml | 9 +++ 11 files changed, 419 insertions(+) create mode 100644 README.md create mode 100644 defaults/main.yml create mode 100644 handlers/main.yml create mode 100644 tasks/configure.yml create mode 100644 tasks/install.yml create mode 100644 tasks/main.yml create mode 100644 templates/Gitlab.gitlab-license.j2 create mode 100644 templates/gitlab-secrets.json.j2 create mode 100644 templates/gitlab.rb.j2 create mode 100644 templates/gitlab.repo.j2 create mode 100644 vars/gitlab_pkg_dependencies.yml diff --git a/README.md b/README.md new file mode 100644 index 0000000..31e1b3b --- /dev/null +++ b/README.md @@ -0,0 +1,62 @@ +Role Name +========= + +This role deploys a gitlab-ee instance and does the following: + +* gitlab installation w/ features +* deploys gitlab.rb +* deploys gitlab-secrets.json +* deploys gitlab ee license +* deploys gitlab host keys +* triggers gitlab reconfiguration + +Requirements +------------ + +* none + +Role Variables +-------------- + +See defaults/main.yml + +Dependencies +------------ + +* none + +Example Playbook +---------------- + +```yaml + - name: playbook to install gitlab + hosts: gitlab + become: yes + roles: + - gitlab +``` + +Additional Information +---------------------- + +Due to the lack of any secret store, the `host_vars` are encrypted using ansible vault and the password of the ansible user. + +How to test: + +``` +$ ansible-playbook -i inventories/lab/hosts plays/gitlab.yml --ask-vault-pass --check --diff +$ ansible-playbook -i inventories/tst/hosts plays/gitlab.yml --ask-vault-pass --check --diff +$ ansible-playbook -i inventories/prd/hosts plays/gitlab.yml --ask-vault-pass --check --diff +``` + +How to see the `host_vars`: + +``` +$ ansible-vault edit inventories/lab/host_vars/mbzex30855.mbmain.migrosbank.ch.yml +$ ansible-vault edit inventories/tst/host_vars/mbztx30855.mbmain.migrosbank.ch.yml +$ ansible-vault edit inventories/prd/host_vars/mbzpx30855.mbmain.migrosbank.ch.yml +``` + +Note: + +If you'd like to see any actual diff output during the test run, you need to remove or disable the `no_log` directive in the configure.yml task. diff --git a/defaults/main.yml b/defaults/main.yml new file mode 100644 index 0000000..6cd12a4 --- /dev/null +++ b/defaults/main.yml @@ -0,0 +1,104 @@ +--- +# vim: ts=2 sw=2 et ft=yaml.ansible + +# Package information +gitlab_edition: 'gitlab-ee' +gitlab_version: '' +gitlab_package_version_serparator: '-' +gitlab_config_path: '/etc/gitlab/' + +# ee license +gitlab_ee_license: 'changeme' + +# templates +gitlab_config_template: 'gitlab.rb.j2' +gitlab_secrets_template: 'gitlab-secrets.json.j2' +gitlab_ee_license_template: 'Gitlab.gitlab-license.j2' + +# Paths and files +gitlab_config_file: '/etc/gitlab/gitlab.rb' +gitlab_secrets_file: '/etc/gitlab/gitlab-secrets.json' +gitlab_ctl_binary: '/usr/bin/gitlab-ctl' +gitlab_ee_license_file: '/etc/gitlab/Gitlab.gitlab-license' + +# install custom repository +gitlab_install_custom_repo: false +gitlab_custom_repo: 'gitlab.repo.j2' + +# ssh configuration +gitlab_import_ssh_host_keys: false +gitlab_ssh_host_keys: + /etc/ssh/ssh_host_rsa_key: 'changeme' + /etc/ssh/ssh_host_ecdsa_key: 'changeme' + /etc/ssh/ssh_host_ed25519_key: 'changeme' + +# gitlab.rb configs +gitlab_conf_external_url: 'changeme' +gitlab_conf_backup_path: 'changeme' +gitlab_conf_ssl_cert_bundle: 'changeme' +gitlab_conf_email_display_name: 'changeme' +gitlab_conf_email_from: 'changeme' +gitlab_conf_email_reply_to: 'changeme' +gitlab_conf_initial_root_pw: 'changeme' +gitlab_conf_initial_shared_runner_registration_token: 'changeme' +gitlab_conf_ldap_enabled: true +gitlab_conf_ldap_servers: + active_directory: true + admin_group: 'changeme' + allow_username_or_email_login: false + base: 'changeme' + bind_dn: 'changeme' + block_auto_created_users: 'changeme' + encryption: 'changeme' + group_base: 'changeme' + host: 'changeme' + label: 'changeme' + password: 'changeme' + port: 389 + sync_ssh_keys: false + ca_file: 'changeme' + uid: 'changeme' + verify_certificates: true +gitlab_conf_manage_backup_path: false +gitlab_conf_omniauth_providers: + identifier: 'changeme' + redirect_uri: 'changeme' + secret: 'changeme' + discovery: true + issuer: 'changeme' + name: 'changeme' + label: 'changeme' +gitlab_conf_nginx_enable: true +gitlab_conf_nginx_redirect_https: true +gitlab_conf_nginx_ssl_certificate: '/etc/gitlab/ssl/gitlab.crt' +gitlab_conf_nginx_ssl_certificate_key: '/etc/gitlab/ssl/gitlab.key' +gitlab_conf_letsencrypt_enable: false + +# gitlab-secrets.json configs +gitlab_secrets_workhorse_token: 'changeme' +gitlab_secrets_shell_token: 'changeme' +gitlab_secrets_rails_key_base: 'changeme' +gitlab_secrets_rails_db_key_base: 'changeme' +gitlab_secrets_rails_otp_key_base: 'changeme' +gitlab_secrets_rails_encrypted_settings_key_base: 'changeme' +gitlab_secrets_rails_openid_connect_signing_key: 'changeme' +gitlab_secrets_rails_ci_jwt_signing_key: 'changeme' +gitlab_secrets_pages_secret: 'changeme' +gitlab_secrets_pages_id: 'changeme' +gitlab_secrets_pages_auth_secret: 'changeme' +gitlab_secrets_pages_api_secret_key: 'changeme' +gitlab_secrets_kas_api_key: 'changeme' +gitlab_secrets_grafana_secret_key: 'changeme' +gitlab_secrets_grafana_gitlab_secret: 'changeme' +gitlab_secrets_grafana_gitlab_application_id: 'changeme' +gitlab_secrets_grafana_admin_password: 'changeme' +gitlab_secrets_grafana_metrics_basic_auth_password: 'changeme' +gitlab_secrets_registry_http_secret: 'changeme' +gitlab_secrets_registry_internal_certificate: 'changeme' +gitlab_secrets_registry_internal_key: 'changeme' +gitlab_secrets_letsencrypt_auto_enabled: 'changeme' +gitlab_secrets_mattermost_invite_salt: 'changeme' +gitlab_secrets_mattermost_file_public_link_salt: 'changeme' +gitlab_secrets_mattermost_sql_at_rest_encrypt_key: 'changeme' +gitlab_secrets_postgresql_internal_certificate: 'changeme' +gitlab_secrets_postresql_internal_key: 'changeme' diff --git a/handlers/main.yml b/handlers/main.yml new file mode 100644 index 0000000..eb2b4a3 --- /dev/null +++ b/handlers/main.yml @@ -0,0 +1,13 @@ +--- +# vim: ts=2 sw=2 et ft=yaml.ansible + +- name: reconfigure gitlab + shell: "gitlab-ctl reconfigure > /dev/null 2>&1" + notify: restart gitlab + register: gitlab_restart + failed_when: "gitlab_restart.rc > 2" + +- name: restart gitlab + service: + name: gitlab-runsvdir.service + state: restarted diff --git a/tasks/configure.yml b/tasks/configure.yml new file mode 100644 index 0000000..701f49f --- /dev/null +++ b/tasks/configure.yml @@ -0,0 +1,43 @@ +--- +# vim: ts=2 sw=2 et ft=yaml.ansible + +- name: copy gitlab configuration file + template: + src: '{{ gitlab_config_template }}' + dest: '{{ gitlab_config_file }}' + owner: root + group: root + mode: 0600 + notify: reconfigure gitlab + no_log: true # do not expose potential secrets + +- name: copy gitlab secrets file + template: + src: gitlab-secrets.json.j2 + dest: /etc/gitlab/gitlab-secrets.json + owner: root + group: root + mode: 0600 + notify: reconfigure gitlab + no_log: true # do not expose potential secrets + +- name: copy license when installing gitlab-ee version + template: + src: '{{ gitlab_ee_license_template }}' + dest: '{{ gitlab_ee_license_file }}' + owner: root + group: root + mode: 0644 + notify: reconfigure gitlab + no_log: true # do not expose potential secrets + when: gitlab_edition == 'gitlab-ee' and gitlab_ee_license | length > 0 + +- name: copy ssh host keys when migrating + copy: + dest: '{{ item.key }}' + content: "{{ item.value }}\n" + owner: root + group: root + mode: 0400 + loop: '{{ gitlab_ssh_host_keys | dict2items }}' + when: gitlab_import_ssh_host_keys diff --git a/tasks/install.yml b/tasks/install.yml new file mode 100644 index 0000000..696d24c --- /dev/null +++ b/tasks/install.yml @@ -0,0 +1,32 @@ +--- +# vim: ts=2 sw=2 et ft=yaml.ansible + +- name: check if gitlab is already installed + stat: + path: '{{ gitlab_ctl_binary }}' + register: gl_binary + +- name: install gitlab dependencies + package: + name: '{{ gitlab_pkg_dependencies }}' + state: present + +- name: add gitlab repository if necessary + template: + src: '{{ gitlab_install_custom_repo }}' + dest: '/etc/yum.repos.d/gitlab_{{ gitlab_edition }}.repo' + owner: root + group: root + mode: 0644 + when: gitlab_install_custom_repo + +- name: assemble gitlab package name + set_fact: + gitlab_package: '{{ gitlab_edition }}{{ gitlab_package_version_separator }}{{ gitlab_version }}' + when: gitlab_version | length > 0 + +- name: install gitlab + package: + name: '{{ gitlab_package | default(gitlab_edition) }}' + state: present + when: not gl_binary.stat.exists diff --git a/tasks/main.yml b/tasks/main.yml new file mode 100644 index 0000000..c1f22f5 --- /dev/null +++ b/tasks/main.yml @@ -0,0 +1,19 @@ +--- +# vim: ts=2 sw=2 et ft=yaml.ansible + +- name: load gitlab package dependency list based on distribution type + include_vars: '{{ item }}' + loop: + - 'gitlab_pkg_dependencies.yml' + tags: + - 'gitlab_vars' + +- name: install gitlab and dependencies + import_tasks: install.yml + tags: + - 'gitlab_install' + +- name: configure gitlab + import_tasks: configure.yml + tags: + - 'gitlab_configure' diff --git a/templates/Gitlab.gitlab-license.j2 b/templates/Gitlab.gitlab-license.j2 new file mode 100644 index 0000000..f145976 --- /dev/null +++ b/templates/Gitlab.gitlab-license.j2 @@ -0,0 +1 @@ +{{ gitlab_ee_license }} diff --git a/templates/gitlab-secrets.json.j2 b/templates/gitlab-secrets.json.j2 new file mode 100644 index 0000000..7431e39 --- /dev/null +++ b/templates/gitlab-secrets.json.j2 @@ -0,0 +1,51 @@ +{ + "gitlab_workhorse": { + "secret_token": "{{ gitlab_secrets_workhorse_token }}" + }, + "gitlab_shell": { + "secret_token": "{{ gitlab_secrets_shell_token }}" + }, + "gitlab_rails": { + "secret_key_base": "{{ gitlab_secrets_rails_key_base }}", + "db_key_base": "{{ gitlab_secrets_rails_db_key_base }}", + "otp_key_base": "{{ gitlab_secrets_rails_otp_key_base }}", + "encrypted_settings_key_base": "{{ gitlab_secrets_rails_encrypted_settings_key_base }}" + "openid_connect_signing_key": "{{ gitlab_secrets_rails_openid_connect_signing_key }}" + "ci_jwt_signing_key": "{{ gitlab_secrets_rails_ci_jwt_signing_key }}" + }, + "gitlab_pages": { + "gitlab_secret": {% if gitlab_secrets_pages_secret | length %}"{{ gitlab_secrets_pages_secret }}"{% else %}null{% endif %}, + "gitlab_id": {% if gitlab_secrets_pages_id | length %}"{{ gitlab_secrets_pages_id }}"{% else %}null{% endif %}, + "auth_secret": {% if gitlab_secrets_pages_auth_secret | length %}"{{ gitlab_secrets_pages_auth_secret }}"{% else %}null{% endif %}, + "api_secret_key": {% if gitlab_secrets_pages_api_secret_key | length %}"{{ gitlab_secrets_pages_api_secret_key }}"{% else %}""{% endif %} + }, + {% if gitlab_kas_api_key is defined %} + "gitlab_kas": { + "api_secret_key": "{{ gitlab_secrets_kas_api_key }}" + }, + {% endif %} + "grafana": { + "secret_key": "{{ gitlab_secrets_grafana_secret_key }}", + "gitlab_secret": "{{ gitlab_secrets_grafana_gitlab_secret }}", + "gitlab_application_id": "{{ gitlab_secrets_grafana_gitlab_application_id }}", + "admin_password": "{{ gitlab_secrets_grafana_admin_password }}", + "metrics_basic_auth_password": {% if gitlab_secrets_grafana_metrics_basic_auth_password | length %}"{{ gitlab_secrets_grafana_metrics_basic_auth_password }}"{% else %}null{% endif %} + }, + "registry": { + "http_secret": "{{ gitlab_secrets_registry_http_secret }}", + "internal_certificate": "{{ gitlab_secrets_registry_internal_certificate }}", + "internal_key": "{{ gitlab_secrets_registry_internal_key }}" + }, + "letsencrypt": { + "auto_enabled": {% if gitlab_secrets_letsencrypt_auto_enabled | length %}"{{ gitlab_secrets_letsencrypt_auto_enabled }}"{% else %}null{% endif %} + }, + "mattermost": { + "email_invite_salt": "{{ gitlab_secrets_mattermost_invite_salt }}", + "file_public_link_salt": "{{ gitlab_secrets_mattermost_file_public_link_salt }}", + "sql_at_rest_encrypt_key": "{{ gitlab_secrets_mattermost_sql_at_rest_encrypt_key }}" + }, + "postgresql": { + "internal_certificate": "{{ gitlab_secrets_postgresql_internal_certificate }}", + "internal_key": "{{ gitlab_secrets_postgresql_internal_key }}" + } +} diff --git a/templates/gitlab.rb.j2 b/templates/gitlab.rb.j2 new file mode 100644 index 0000000..bf597db --- /dev/null +++ b/templates/gitlab.rb.j2 @@ -0,0 +1,75 @@ +# vim: ts=2 sw=2 et ft=ruby + +# general configs + +external_url '{{ gitlab_conf_external_url }}' + +# gitlab configs + +gitlab_rails['backup_path'] = "{{ gitlab_conf_backup_path }}" +gitlab_rails['env'] = {"SSL_CERT_FILE"=>"{{ gitlab_conf_ssl_cert_bundle }}"} +gitlab_rails['gitlab_email_display_name'] = "{{ gitlab_conf_email_display_name }}" +gitlab_rails['gitlab_email_from'] = "{{ gitlab_conf_email_from }}" +gitlab_rails['gitlab_email_reply_to'] = "{{ gitlab_conf_email_reply_to }}" +gitlab_rails['initial_root_password'] = "{{ gitlab_conf_initial_root_pw }}" +gitlab_rails['initial_shared_runners_registration_token'] = "{{ gitlab_conf_initial_shared_runner_registration_token }}" +gitlab_rails['ldap_enabled'] = {{ gitlab_conf_ldap_enabled }} +gitlab_rails['manage_backup_path'] = {{ gitlab_conf_manage_backup_path }} +gitlab_rails['ldap_servers'] = { + "main"=>{ + "active_directory"=>{{ gitlab_conf_ldap_servers.active_directory }}, + "admin_group"=>"{{ gitlab_conf_ldap_servers.admin_group }}", + "allow_username_or_email_login"=>{{ gitlab_conf_ldap_servers.allow_username_or_email_login }}, + "attributes"=>{ + "email"=>["mail", "email", "userPrincipalName"], + "first_name"=>"givenName", + "last_name"=>"sn", + "name"=>"nosuchattribute", + "username"=>["uid", "userid", "sAMAccountName"] + }, + "base"=>"{{ gitlab_conf_ldap_servers.base }}", + "bind_dn"=>"{{ gitlab_conf_ldap_servers.bind_dn }}", + "block_auto_created_users"=>{{ gitlab_conf_ldap_servers.block_auto_created_users }}, + "encryption"=>"{{ gitlab_conf_ldap_servers.encryption }}", + "group_base"=>"{{ gitlab_conf_ldap_servers.group_base }}", + "host"=>"{{ gitlab_conf_ldap_servers.host }}", + "label"=>"{{ gitlab_conf_ldap_servers.label }}", + "password"=>"{{ gitlab_conf_ldap_servers.password }}", + "port"=>"{{ gitlab_conf_ldap_servers.port }}", + "sync_ssh_keys"=>{{ gitlab_conf_ldap_servers.sync_ssh_keys }}, + "tls_options"=>{ + "ca_file"=>"{{ gitlab_conf_ldap_servers.ca_file }}", + }, + "uid"=>"{{ gitlab_conf_ldap_servers.uid }}", + "verify_certificates"=>{{ gitlab_conf_ldap_servers.verify_certificates }}, + } +} +gitlab_rails['omniauth_providers'] = [{ + "args"=>{ + "client_options"=>{ + "identifier"=>"{{ gitlab_conf_omniauth_providers.identifier }}", + "redirect_uri"=>"{{ gitlab_conf_omniauth_providers.redirect_uri }}", + "secret"=>"{{ gitlab_conf_omniauth_providers.secret }}", + }, + "discovery"=>{{ gitlab_conf_omniauth_providers.discovery }}, + "issuer"=>"{{ gitlab_conf_omniauth_providers.issuer }}", + "name"=>"{{ gitlab_conf_omniauth_providers.name }}", + "response_type"=>"code", + "scope"=>["openid", "profile"] + }, + "label"=>"{{ gitlab_conf_omniauth_providers.label }}", + "name"=>"openid_connect" +}] + +# nginx configs + +nginx['enable'] = {{ gitlab_conf_nginx_enable }} +nginx['redirect_http_to_https'] = {{ gitlab_conf_nginx_redirect_https }} +nginx['ssl_certificate'] = "{{ gitlab_conf_nginx_ssl_certificate }}" +nginx['ssl_certificate_key'] = "{{ gitlab_conf_nginx_ssl_certificate_key }}" + +# letsencrypt configs + +letsencrypt['enable'] = {{ gitlab_conf_letsencrypt_enable }} + + diff --git a/templates/gitlab.repo.j2 b/templates/gitlab.repo.j2 new file mode 100644 index 0000000..7834ecc --- /dev/null +++ b/templates/gitlab.repo.j2 @@ -0,0 +1,10 @@ +{{ ansible_managed | comment }} +[gitlab_gitlab-ee] +name=gitlab_gitlab-ee +baseurl={{ gitlab_repo_base_url }} +repo_gpgcheck=0 +gpgcheck=0 +enabled=1 +sslverify=1 +sslcacert={{ gitlab_cacert_bundle }} +metadata_expire=300 diff --git a/vars/gitlab_pkg_dependencies.yml b/vars/gitlab_pkg_dependencies.yml new file mode 100644 index 0000000..08e6d1a --- /dev/null +++ b/vars/gitlab_pkg_dependencies.yml @@ -0,0 +1,9 @@ +--- +# vim: ts=2 sw=2 et ft=yaml.ansible + +gitlab_pkg_dependencies: + - openssh-server + - postfix + - curl + - openssl + - tzdata