refactor(examples/gitlab): move role to ansible's folder

This commit is contained in:
Michele Cereda
2024-05-08 18:48:11 +02:00
parent 81d263417b
commit 7f93a9b50d
22 changed files with 302 additions and 141 deletions

View File

@@ -0,0 +1,14 @@
---
install_method: package
external_url: https://{{ ansible_fqdn }}
gitlab_version: null
# Random but idempotent, so it will not change every time the role is applied.
# It is only used for installation anyways.
initial_password: "{{ lookup('ansible.builtin.password', '/dev/null', seed=inventory_hostname) }}"
certificate_privatekey_type: RSA
certificate_privatekey_rsa_size: 2048
certificate_must_be_wildcard: false
certificate_dir: /etc/gitlab/ssl

View File

@@ -0,0 +1,23 @@
[gitlab_gitlab-ee]
name=gitlab_gitlab-ee
baseurl=https://packages.gitlab.com/gitlab/gitlab-ee/amazon/2023/$basearch
repo_gpgcheck=1
gpgcheck=1
enabled=1
gpgkey=https://packages.gitlab.com/gitlab/gitlab-ee/gpgkey
https://packages.gitlab.com/gitlab/gitlab-ee/gpgkey/gitlab-gitlab-ee-3D645A26AB9FBD22.pub.gpg
sslverify=1
sslcacert=/etc/pki/tls/certs/ca-bundle.crt
metadata_expire=300
[gitlab_gitlab-ee-source]
name=gitlab_gitlab-ee-source
baseurl=https://packages.gitlab.com/gitlab/gitlab-ee/amazon/2023/SRPMS
repo_gpgcheck=1
gpgcheck=1
enabled=1
gpgkey=https://packages.gitlab.com/gitlab/gitlab-ee/gpgkey
https://packages.gitlab.com/gitlab/gitlab-ee/gpgkey/gitlab-gitlab-ee-3D645A26AB9FBD22.pub.gpg
sslverify=1
sslcacert=/etc/pki/tls/certs/ca-bundle.crt
metadata_expire=300

View File

@@ -0,0 +1,65 @@
---
- name: Create the DNS TXT record for challenge validation
when: external_url_hostname in dns_challenge.challenge_data
tags:
- aws
- route53
become: true
amazon.aws.route53:
zone: apolloagriculture.com # FIXME
record: "{{ dns_challenge.challenge_data[external_url_hostname]['dns-01'].record }}"
type: TXT
ttl: 60
state: present
overwrite: true
wait: true
value:
# Value should be enclosed in quotation marks
>-
{{
dns_challenge.challenge_data[external_url_hostname]['dns-01'].resource_value
| regex_replace('^(.*)$', '"\1"')
}}
notify:
- Validate the challenge and issue the certificate
- Remove the TXT record for challenge validation from the DNS
- "Restart Gitlab's nginx"
- name: Validate the challenge and issue the certificate
become: true
community.crypto.acme_certificate:
challenge: dns-01
acme_version: 2
acme_directory: https://acme-v02.api.letsencrypt.org/directory
account_key_src: "{{ letsencrypt_privatekey_path }}"
account_email: "{{ acme_account_email }}"
csr: "{{ certificate_csr_path }}"
cert: "{{ certificate_path }}"
remaining_days: 29
terms_agreed: true
data: "{{ dns_challenge }}"
force: true # required to overwrite existing certificates
register: certificate_validation
- name: Remove the TXT record for challenge validation from the DNS
vars:
validation_record: "{{ ['_acme-challenge', external_url_hostname] | join('.') }}"
when:
- certificate_validation is not failed
- query('community.dns.lookup', validation_record, type='TXT') != []
tags:
- aws
- route53
become: true
amazon.aws.route53:
zone: apolloagriculture.com # FIXME
record: "{{ validation_record }}"
type: TXT
state: absent
wait: true
- name: "Restart Gitlab's nginx"
when: certificate_validation is not failed
become: true
ansible.builtin.command: gitlab-ctl restart 'nginx'

View File

@@ -0,0 +1,22 @@
---
- name: "Validate Gitlab's configuration file"
become: true
ansible.builtin.command: gitlab-ctl show-config
register: config_file_validation
changed_when: false
failed_when: config_file_validation.rc != 0
- name: Reconfigure Gitlab
when: config_file_validation is not failed
become: true
ansible.builtin.command: gitlab-ctl reconfigure
register: reconfiguration
changed_when:
- reconfiguration.rc == 0
- >-
(
reconfiguration.stdout
| regex_findall('Infra Phase complete, .*')
) is not search('0/')
failed_when: reconfiguration.rc != 0

View File

@@ -0,0 +1,16 @@
---
- name: Show the settings for initial access
tags:
- credentials
- initial
- password
ansible.builtin.debug:
msg: >-
{{
dict([
[ 'URL', external_url ],
[ 'Username', 'root' ],
[ 'Initial Password', initial_password ]
])
}}

View File

@@ -0,0 +1,27 @@
---
- name: Load installation handlers
tags:
- "{{ install_method }}"
- gitlab
- install
ansible.builtin.import_tasks:
file: "{{ role_path }}/handlers/install/{{ install_method }}.yml"
- name: Load configuration handlers
tags:
- "{{ install_method }}"
- configuration
- configure
- gitlab
ansible.builtin.import_tasks:
file: "{{ role_path }}/handlers/configure/{{ install_method }}.yml"
- name: Load certification handlers
tags:
- "{{ install_method }}"
- certificate
- certify
- gitlab
ansible.builtin.import_tasks:
file: "{{ role_path }}/handlers/certify/{{ install_method }}.yml"

View File

@@ -0,0 +1,6 @@
---
collections:
- amazon.aws
- community.crypto
- community.dns

View File

@@ -0,0 +1,52 @@
---
- name: Set up the requirements
block:
- name: Install required python libraries
become: true
ansible.builtin.package:
name: python3-boto3
- name: Ensure the destination folder exists
check_mode: false
become: true
ansible.builtin.file:
path: "{{ certificate_dir }}"
state: directory
owner: root
group: root
mode: u=rwx,g=rx,o=rx
- name: Generate OpenSSL private keys for the account and the certificate
become: true
community.crypto.openssl_privatekey:
path: "{{ item }}"
type: "{{ certificate_privatekey_type }}"
size: "{{ (certificate_privatekey_type == 'RSA') | ternary(certificate_privatekey_rsa_size, omit) }}"
regenerate: partial_idempotence
backup: true
with_items:
- "{{ certificate_privatekey_path }}"
- "{{ letsencrypt_privatekey_path }}"
- name: Generate the CRS for the certificate
become: true
community.crypto.openssl_csr:
path: "{{ certificate_csr_path }}"
privatekey_path: "{{ certificate_privatekey_path }}"
common_name: "{{ certificate_csr_commonname }}"
- name: Create the DNS challenge for '{{ external_url_hostname }}'
become: true
community.crypto.acme_certificate:
challenge: dns-01
acme_version: 2
acme_directory: https://acme-v02.api.letsencrypt.org/directory
account_key_src: "{{ letsencrypt_privatekey_path }}"
account_email: "{{ acme_account_email }}"
csr: "{{ certificate_csr_path }}"
cert: "{{ certificate_path }}"
terms_agreed: true
remaining_days: 29
register: dns_challenge
notify: Create the DNS TXT record for challenge validation

View File

@@ -0,0 +1,32 @@
---
- name: Ensure the destination folder exists
check_mode: false
become: true
ansible.builtin.file:
path: /etc/gitlab
state: directory
owner: root
group: root
mode: u=rwx,g=rwx,o=rx
- name: Create the configuration file
become: true
ansible.builtin.template:
src: gitlab.rb.j2
dest: /etc/gitlab/gitlab.rb
owner: root
group: root
mode: u=rw,g=,o=
backup: true
notify:
- "Validate Gitlab's configuration file"
- Reconfigure Gitlab
- name: Configure settings that are unreachable from the configuration file
become: true
ansible.builtin.command: >-
gitlab-rails runner '
::Gitlab::CurrentSettings.update!(signup_enabled: false);
'
changed_when: true

View File

@@ -0,0 +1,46 @@
---
# Follow 'https://about.gitlab.com/install/#amazonlinux-2023'.
- name: Add Gitlab's repositories
tags:
- repo
- repository
- repositories
become: true
ansible.builtin.yum_repository:
# Refer 'files/yum.gitlab_gitlab-ee.repo'.
name: "{{ item.name }}"
description: "{{ item.description }}"
baseurl: "{{ item.baseurl }}"
repo_gpgcheck: true
gpgcheck: true
gpgkey: |-
https://packages.gitlab.com/gitlab/gitlab-ee/gpgkey
https://packages.gitlab.com/gitlab/gitlab-ee/gpgkey/gitlab-gitlab-ee-3D645A26AB9FBD22.pub.gpg
sslverify: true
sslcacert: /etc/pki/tls/certs/ca-bundle.crt
metadata_expire: 300
protect: true
with_items:
- name: gitlab-ee
description: gitlab-ee
baseurl: https://packages.gitlab.com/gitlab/gitlab-ee/amazon/2023/$basearch
- name: gitlab-ee-source
description: gitlab-ee-source
baseurl: https://packages.gitlab.com/gitlab/gitlab-ee/amazon/2023/SRPMS
- name: Install Gitlab's omnibus package
tags:
- package
environment:
EXTERNAL_URL: "{{ external_url }}"
GITLAB_ROOT_PASSWORD: "{{ initial_password }}"
become: true
ansible.builtin.package:
name: >-
{{
(gitlab_version is ansible.builtin.version('16.9.0', '>=', version_type='semver'))
| ternary(['gitlab-ee', gitlab_version] | join('-'), 'gitlab-ee')
}}
notify: Show the settings for initial access

View File

@@ -0,0 +1,33 @@
---
- name: Pre-flight checks
tags:
- check
- checks
- pre-flight
- preflight
ansible.builtin.import_tasks:
file: pre-flight.yml
- name: Install Gitlab
tags:
- "{{ install_method }}"
- gitlab
- install
ansible.builtin.import_tasks:
file: "{{ role_path }}/tasks/install/{{ install_method }}.yml"
- name: Configure Gitlab
tags:
- "{{ install_method }}"
- configure
- gitlab
ansible.builtin.import_tasks:
file: "{{ role_path }}/tasks/configure/{{ install_method }}.yml"
- name: Validate certificate for '{{ external_url_hostname }}'
tags:
- "{{ install_method }}"
- certificate
- certify
- gitlab
ansible.builtin.import_tasks:
file: "{{ role_path }}/tasks/certify/{{ install_method }}.yml"

View File

@@ -0,0 +1,49 @@
---
- name: Check the requested install method is supported by the role
ansible.builtin.assert:
that: install_method in supported_install_methods
fail_msg: >-
Install method '{{ install_method }}' not supported by the role, 'install_method' must be one of
{{ supported_install_methods }}
success_msg: Install method '{{ install_method }}' supported by the role
- name: Check the initial password is null or a valid string
ansible.builtin.assert:
that: initial_password != ''
fail_msg: Initial password setting not supported by the role, 'initial_password' must be either null or not empty
success_msg: Initial password setting supported by the role
- name: Check the given external URL is valid
block:
- name: Check the external URL is a valid URL
ansible.builtin.assert:
that: external_url is ansible.builtin.url
fail_msg: External URL '{{ external_url }}' is not a valid URL, set 'external_url' to a valid one
success_msg: External URL '{{ external_url }}' is a valid URL
- name: Check the external URL's scheme is supported by the role
ansible.builtin.assert:
that: external_url_scheme in supported_external_url_schemes
fail_msg: >-
External URL scheme '{{ external_url_scheme }}' not supported by the role, set 'external_url' to have one of
{{ supported_external_url_schemes }}
success_msg: External URL scheme '{{ external_url_scheme }}' supported by the role
- name: Check the requirements for certificate validation
when: external_url_scheme == 'https'
block:
- name: Check the given acme account email is in a valid email format
ansible.builtin.assert:
that: ('mailto://' + acme_account_email) is ansible.builtin.url
fail_msg: >-
Acme account email '{{ acme_account_email }}' is not a valid email, set 'acme_account_email' to a valid one
success_msg: Acme account email '{{ acme_account_email }}' is a valid email
- name: Check an A or AAAA DNS record already exists for '{{ external_url_hostname }}'
ansible.builtin.assert:
that: >-
query('community.dns.lookup', external_url_hostname) != [] or
query('community.dns.lookup', external_url_hostname, type='AAAA') != []
fail_msg: >-
Certificate validation requested but no required DNS entry of type 'A' or 'AAAA' found for
'{{ external_url_hostname }}', create one first
success_msg: Required DNS entry found for '{{ external_url_hostname }}'

View File

@@ -0,0 +1,12 @@
## GitLab configuration settings
## -------------------------------------
## Template for the local installation available at
## /opt/gitlab/etc/gitlab.rb.template
# URL on which GitLab will be reachable.
# During installation/upgrades, the value of the environment variable 'EXTERNAL_URL' will be used to populate/replace
# this value.
external_url '{{ external_url }}'
# LetsEncrypt integration
letsencrypt['enable'] = false

View File

@@ -0,0 +1,24 @@
---
external_url_hostname: "{{ external_url | ansible.builtin.urlsplit('hostname') }}"
external_url_scheme: "{{ external_url | ansible.builtin.urlsplit('scheme') }}"
supported_external_url_schemes:
- http
- https
supported_install_methods:
- package
certificate_csr_commonname: >-
{{
certificate_must_be_wildcard
| ternary(['*', external_url_hostname] | join('.'), external_url_hostname)
}}
certificate_csr_name: "{{ [external_url_hostname, 'csr'] | join('.') }}"
certificate_csr_path: "{{ [certificate_dir, certificate_csr_name] | path_join }}"
certificate_name: "{{ [external_url_hostname, 'crt'] | join('.') }}"
certificate_path: "{{ [certificate_dir, certificate_name] | path_join }}"
certificate_privatekey_name: "{{ [external_url_hostname, 'key'] | join('.') }}"
certificate_privatekey_path: "{{ [certificate_dir, certificate_privatekey_name] | path_join }}"
letsencrypt_privatekey_name: letsencrypt_account_private_key.pem
letsencrypt_privatekey_path: "{{ [certificate_dir, letsencrypt_privatekey_name] | path_join }}"