1 Commits

Author SHA1 Message Date
610b796763 feat: add playbook for managing LDAP directory contents 2025-05-06 23:22:50 +02:00
8 changed files with 14 additions and 213 deletions

View File

@@ -1,6 +1,6 @@
namespace: finallycoffee namespace: finallycoffee
name: base name: base
version: 0.4.0 version: 0.3.0
readme: README.md readme: README.md
authors: authors:
- transcaffeine <transcaffeine@finally.coffee> - transcaffeine <transcaffeine@finally.coffee>
@@ -8,9 +8,8 @@ description: >-2
Roles for base services which are core functionality like managing packages Roles for base services which are core functionality like managing packages
and ssh or common dependencies other services like databases and ssh or common dependencies other services like databases
dependencies: dependencies:
"community.docker": "^4.7.0" "community.docker": "^4.2.0"
"community.general": "^11.1.2" "community.general": "^10.0.0"
"containers.podman": "^1.17.0"
license_file: LICENSE.md license_file: LICENSE.md
build_ignore: build_ignore:
- '*.tar.gz' - '*.tar.gz'

View File

@@ -9,10 +9,6 @@
server_uri: "{{ ldap_server_uri }}" server_uri: "{{ ldap_server_uri }}"
bind_dn: "{{ ldap_bind_dn }}" bind_dn: "{{ ldap_bind_dn }}"
bind_pw: "{{ ldap_bind_pw }}" bind_pw: "{{ ldap_bind_pw }}"
roles:
# Ensure all defaults from openldap role are in scope
- role: finallycoffee.base.openldap
when: false
tasks: tasks:
- name: Ensure org units in '{{ ldap_base_dn }}' are {{ _state }} - name: Ensure org units in '{{ ldap_base_dn }}' are {{ _state }}
community.general.ldap_entry: community.general.ldap_entry:
@@ -23,87 +19,3 @@
loop: "{{ ldap_org_units | default([], true) }}" loop: "{{ ldap_org_units | default([], true) }}"
loop_control: loop_control:
loop_var: org_unit loop_var: org_unit
- name: Ensure admin user is {{ _state }}
community.general.ldap_entry:
<<: *ldap_bind_info
dn: "uid={{ ldap_admin_user_rdn }},{{ ldap_admin_user_base }}"
objectClass: "{{ ldap_admin_user_object_classes }}"
attributes: "{{ ldap_admin_user_attributes }}"
state: "{{ _state }}"
vars:
ldap_admin_user_base: >-2
{{ ldap_admin_user_base_dn | default(ldap_base_dn, true) }}
when: ldap_admin_user_rdn is defined
- name: Ensure admin user attributes are correct
community.general.ldap_attrs:
<<: *ldap_bind_info
dn: "uid={{ ldap_admin_user_rdn }},{{ ldap_admin_user_base }}"
attributes: "{{ ldap_admin_user_attributes }}"
state: "{{ _state }}"
vars:
ldap_admin_user_base: >-2
{{ ldap_admin_user_base_dn | default(ldap_base_dn, true) }}
when:
- ldap_admin_user_rdn is defined
- _state == 'present'
- name: Ensure ldap groups are {{ _state }}
community.general.ldap_entry:
<<: *ldap_bind_info
dn: "{{ _ldap_group_dn }}"
objectClass: "{{ _ldap_group_object_classes }}"
attributes: "{{ _ldap_group_attributes }}"
state: "{{ _state }}"
vars:
_ldap_group_dn: >-2
cn={{ _ldap_group.name }},{{ ldap_group_base_dn }}
_ldap_group_object_classes:
- "groupOfNames"
_ldap_group_attributes:
cn: "{{ _ldap_group.name }}"
member: >-2
{{ _ldap_group.members | default([]) }}
loop: "{{ ldap_groups | default([], true) }}"
loop_control:
loop_var: _ldap_group
label: "{{ _ldap_group.name }}"
when:
- ldap_groups is defined
- ldap_group_base_dn is defined
- name: Ensure service accounts are {{ _state }}
community.general.ldap_entry:
<<: *ldap_bind_info
dn: "{{ _ldap_service_account_dn }}"
objectClass: "{{ _ldap_service_account_object_classes }}"
attributes: "{{ _ldap_service_account_attributes }}"
state: "{{ _state }}"
loop: &ldap_service_account_loop "{{ ldap_service_accounts | default([]) }}"
loop_control: &ldap_service_account_loop_control
loop_var: "_ldap_service_account"
label: "{{ _ldap_service_account.name }}"
vars: &ldap_service_account_vars
_ldap_service_account_dn: >-2
uid={{ _ldap_service_account.name }},{{ ldap_service_account_base_dn }}
_ldap_service_account_object_classes:
- "account"
- "simpleSecurityObject"
_ldap_service_account_attributes:
uid: "{{ _ldap_service_account.name }}"
userPassword: "{{ _ldap_service_account.password }}"
when: &ldap_service_account_when
- ldap_service_accounts is defined
- ldap_service_account_base_dn is defined
- name: Ensure service accounts attributes are correct
community.general.ldap_attrs:
<<: *ldap_bind_info
dn: "{{ _ldap_service_account_dn }}"
attributes: "{{ _ldap_service_account_attributes }}"
state: exact
loop: *ldap_service_account_loop
loop_control: *ldap_service_account_loop_control
vars: *ldap_service_account_vars
when: *ldap_service_account_when

View File

@@ -1,85 +0,0 @@
---
- name: Populate DNS, acquire TSIG key and obtain certificate
hosts: "{{ target_hosts | default('all') }}"
become: "{{ target_become | default(true) }}"
gather_facts: "{{ target_gather_facts | default(false) }}"
pre_tasks:
- name: Build target dns records
ansible.builtin.set_fact:
target_dns_records: "{{ target_dns_records + [ _dns_record ] }}"
vars:
_dns_record:
type: "CNAME"
name: "_acme-challenge.{{ _domain }}"
content: "{{ target_tsig_key_name }}.{{ target_acme_zone }}."
loop: "{{ target_domains }}"
loop_control:
loop_var: "_domain"
- name: Populate dns_server if not given
ansible.builtin.set_fact:
dns_server: "{{ target_dns_server }}"
when: dns_server is not defined
roles:
- role: finallycoffee.base.dns
vars:
dns_records: "{{ target_dns_records + target_dns_additional_records }}"
dns_tsig_name: "{{ target_dns_tsig_key.name }}"
dns_tsig_algo: "{{ target_dns_tsig_key.algorithm }}"
dns_tsig_key: "{{target_dns_tsig_key.key }}"
delegate_to: localhost
- role: finallycoffee.base.powerdns_tsig_key
vars:
powerdns_tsig_key_algo: "{{ target_powerdns_tsig_key_algo }}"
powerdns_tsig_key_name: "{{ target_tsig_key_name }}"
powerdns_tsig_key_path: "{{ target_tsig_key_path }}"
powerdns_tsig_key_path_owner: "{{ target_acme_user }}"
powerdns_tsig_key_path_group: "{{ target_acme_group }}"
- role: finallycoffee.base.lego
vars:
lego_instance: "{{ target_lego_instance }}"
lego_instance_base_path: "{{ target_lego_instance_base_path }}"
lego_environment: "{{ target_lego_environment }}"
lego_cert_domains: "{{ target_lego_domains }}"
lego_acme_account_email: "{{ target_acme_account_email }}"
lego_acme_challenge_type: "{{ target_lego_acme_challenge_type }}"
lego_acme_challenge_provider: "{{ target_lego_acme_challenge_provider }}"
lego_acme_server_url: "{{ target_lego_acme_server_url }}"
vars:
target_domains: []
target_acme_zone: ~
target_acme_account_email: ~
target_dns_server: ~
target_dns_additional_records: []
target_dns_tsig_key: {}
target_lego_instance: "{{ target_domains | first }}"
target_lego_instance_base_path: "/opt/acme"
target_lego_domains: "{{ target_domains }}"
target_lego_acme_challenge_type: "dns"
target_lego_acme_challenge_provider: "rfc2136"
target_lego_acme_server_url: >-2
{{ lego_letsencrypt_server_urls.prod }}
target_lego_environment:
RFC2136_TSIG_KEY: "{{ target_tsig_key_name }}"
RFC2136_TSIG_SECRET_FILE: "{{ target_tsig_key_path }}"
RFC2136_TSIG_ALGORITHM: "{{ target_powerdns_tsig_key_algo }}"
RFC2136_NAMESERVER: "{{ target_dns_server }}"
RFC2136_DNS_TIMEOUT: 15
RFC2136_TTL: 60
RFC2136_SEQUENCE_INTERVAL: 5
RFC2136_POLLING_INTERVAL: 10
RFC2136_PROPAGATION_TIMEOUT: >-2
{{ (target_lego_domains | length * 120) | int }}
LEGO_EXPERIMENTAL_CNAME_SUPPORT: "true"
target_tsig_key_name: "{{ target_lego_instance | hash('sha1') }}"
target_tsig_key_path: >-2
{{ target_lego_instance_base_path }}/{{ target_lego_instance }}/secrets/rfc2136_tsig.key
target_tsig_key_path_owner:
target_tsig_key_path_group:
target_acme_user: "acme-{{ target_lego_instance }}"
target_acme_user_id: >-2
{{ powerdns_tsig_key_path_owner_info.uid }}
target_acme_group: "acme-{{ target_lego_instance }}"
target_acme_group_id: >-2
{{ powerdns_tsig_key_path_owner_info.gid }}
target_powerdns_tsig_key_algo: "hmac-sha256"
target_dns_records: []

View File

@@ -1,6 +1,6 @@
--- ---
lego_user: "lego" lego_user: "lego"
lego_version: "4.25.2" lego_version: "4.23.0"
lego_instance: default lego_instance: default
lego_base_path: "/opt/lego" lego_base_path: "/opt/lego"
lego_cert_user: "acme-{{ lego_instance }}" lego_cert_user: "acme-{{ lego_instance }}"

View File

@@ -1,7 +1,7 @@
--- ---
minio_container_name: minio minio_container_name: minio
minio_container_image_name: "docker.io/minio/minio" minio_container_image_name: "docker.io/minio/minio"
minio_container_image_tag: "RELEASE.2025-07-23T15-54-02Z" minio_container_image_tag: "RELEASE.2025-04-22T22-12-26Z"
minio_container_image: "{{ minio_container_image_name }}:{{ minio_container_image_tag }}" minio_container_image: "{{ minio_container_image_name }}:{{ minio_container_image_tag }}"
minio_container_networks: [] minio_container_networks: []
minio_container_ports: [] minio_container_ports: []

View File

@@ -1,5 +1,5 @@
--- ---
nginx_version: "1.29.1" nginx_version: "1.28.0"
nginx_flavour: alpine nginx_flavour: alpine
nginx_base_path: /opt/nginx nginx_base_path: /opt/nginx
nginx_config_file: "{{ nginx_base_path }}/nginx.conf" nginx_config_file: "{{ nginx_base_path }}/nginx.conf"

View File

@@ -26,13 +26,11 @@ openldap_additional_schemas: []
openldap_schemas: >-2 openldap_schemas: >-2
{{ openldap_enabled_schemas + openldap_additional_schemas }} {{ openldap_enabled_schemas + openldap_additional_schemas }}
openldap_config_dn: "cn=config" openldap_config_db: "cn=config"
openldap_config_db_dn: "olcDatabase={0}config,cn=config" openldap_config_db_olc_access: >-2
openldap_config_db_olc_access: to *
- '{0} to * by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" manage
by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" manage by * none
by * none'
openldap_config_attributes: {}
openldap_config_db_attributes: openldap_config_db_attributes:
olcAccess: "{{ openldap_config_db_olc_access }}" olcAccess: "{{ openldap_config_db_olc_access }}"
@@ -51,7 +49,7 @@ openldap_default_database_directory: >-2
openldap_default_database_indices: >-2 openldap_default_database_indices: >-2
{{ openldap_default_indices + openldap_indices }} {{ openldap_default_indices + openldap_indices }}
openldap_default_database_config: >-2 openldap_default_database_config: >-2
olcDatabase={1}{{ openldap_default_database_name }},{{ openldap_config_dn }} olcDatabase={1}{{ openldap_default_database_name }},{{ openldap_config_db }}
openldap_default_database: openldap_default_database:
name: "{{ openldap_default_database_name }}" name: "{{ openldap_default_database_name }}"
object_class: "{{ openldap_default_database_object_class }}" object_class: "{{ openldap_default_database_object_class }}"
@@ -60,6 +58,5 @@ openldap_default_database:
root_pw: "{{ openldap_default_database_root_pw }}" root_pw: "{{ openldap_default_database_root_pw }}"
directory: "{{ openldap_default_database_directory }}" directory: "{{ openldap_default_database_directory }}"
indices: "{{ openldap_default_database_indices }}" indices: "{{ openldap_default_database_indices }}"
openldap_default_database_olc_access: "{{ openldap_config_db_olc_access }}"
openldap_databases: openldap_databases:
- "{{ openldap_default_database }}" - "{{ openldap_default_database }}"

View File

@@ -1,31 +1,9 @@
--- ---
- name: Ensure config attributes are configured - name: Ensure ACLs are configured
community.general.ldap_attrs:
dn: "{{ openldap_config_dn }}"
attributes: "{{ { entry.key : entry.value } }}"
state: exact
server_uri: "{{ openldap_socket_url }}"
loop: "{{ openldap_config_attributes | dict2items }}"
loop_control:
loop_var: "entry"
label: "{{ entry.key }}"
- name: Ensure config db attributes are configured
community.general.ldap_attrs:
dn: "{{ openldap_config_db_dn }}"
attributes: "{{ { entry.key : entry.value } }}"
state: exact
server_uri: "{{ openldap_socket_url }}"
loop: "{{ openldap_config_db_attributes | dict2items }}"
loop_control:
loop_var: "entry"
label: "{{ entry.key }}"
- name: Ensure ACLs for default database are configured
community.general.ldap_attrs: community.general.ldap_attrs:
dn: "{{ openldap_default_database_config }}" dn: "{{ openldap_default_database_config }}"
attributes: attributes:
olcAccess: "{{ openldap_default_database_olc_access }}" olcAccess: "{{ openldap_config_db_olc_access }}"
state: "exact" state: "exact"
server_uri: "{{ openldap_socket_url }}" server_uri: "{{ openldap_socket_url }}"
retries: 3 retries: 3