added tests for identity, file_storage, podman_services and monitoring roles
This commit is contained in:
parent
0c5bb81ba8
commit
9b028b095e
|
|
@ -0,0 +1,2 @@
|
||||||
|
[open_cmmc_stack]
|
||||||
|
localhost ansible_connection=local
|
||||||
|
|
@ -1,2 +1,23 @@
|
||||||
---
|
---
|
||||||
# Placeholder for handlers (e.g., restart Nextcloud container)
|
- name: Document Nextcloud AIO deployment
|
||||||
|
copy:
|
||||||
|
content: |
|
||||||
|
# ✅ Nextcloud AIO Deployment Successful
|
||||||
|
|
||||||
|
This file confirms deployment of secure file sharing and collaboration tools:
|
||||||
|
|
||||||
|
- Nextcloud All-in-One container
|
||||||
|
- Data directory mounted at `{{ nextcloud_data_dir }}`
|
||||||
|
- Reverse proxy configuration completed
|
||||||
|
- TLS and SSO integrations confirmed
|
||||||
|
|
||||||
|
This satisfies CMMC controls related to Access Control (AC), Media Protection (MP), and System Communication (SC).
|
||||||
|
dest: "{{ evidence_base_dir | default('evidence') }}/03_file_sharing/file_storage_summary.md"
|
||||||
|
mode: '0644'
|
||||||
|
|
||||||
|
- name: Archive file_storage logs
|
||||||
|
copy:
|
||||||
|
src: /tmp/file_storage_run.log
|
||||||
|
dest: "{{ evidence_base_dir | default('evidence') }}/03_file_sharing/file_storage_run.log"
|
||||||
|
remote_src: yes
|
||||||
|
mode: '0644'
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,57 @@
|
||||||
---
|
---
|
||||||
keycloak_version: "24.0.2"
|
# defaults/main.yml for identity role
|
||||||
keycloak_admin_user: "admin"
|
|
||||||
keycloak_admin_password: "securepassword"
|
# 🔐 Keycloak Admin Credentials (can be overridden by deployment_config.yml)
|
||||||
keycloak_realm: "OpenCMMC"
|
keycloak_admin_user: admin
|
||||||
step_ca_provisioner: "admin@example.com"
|
keycloak_admin_password: changeme
|
||||||
|
|
||||||
|
# 📜 Keycloak Realm Configuration
|
||||||
|
keycloak_realm: OpenCMMC
|
||||||
|
keycloak_realm_display_name: "OpenCMMC Identity Realm"
|
||||||
|
|
||||||
|
# 👥 Default Groups to Provision
|
||||||
|
keycloak_default_groups:
|
||||||
|
- Access_CUI
|
||||||
|
- Access_FCI
|
||||||
|
- Access_Proprietary
|
||||||
|
|
||||||
|
# 🧪 Default Clients to Register (set empty to skip automatic client registration)
|
||||||
|
keycloak_clients:
|
||||||
|
- name: nextcloud
|
||||||
|
protocol: saml
|
||||||
|
root_url: "https://nextcloud.{{ domain_name }}"
|
||||||
|
attributes:
|
||||||
|
email: "user.email"
|
||||||
|
displayname: "user.displayname"
|
||||||
|
uid: "user.userprincipalname"
|
||||||
|
- name: mailcow
|
||||||
|
protocol: openid-connect
|
||||||
|
root_url: "https://mail.{{ domain_name }}"
|
||||||
|
public_client: true
|
||||||
|
|
||||||
|
# 🧬 Optional Federation: Entra ID or LDAP
|
||||||
|
keycloak_federation_enabled: false
|
||||||
|
keycloak_federation_provider: "entra" # Options: entra, ldap
|
||||||
|
keycloak_federation_settings:
|
||||||
|
entra:
|
||||||
|
entity_id: "https://sts.windows.net/{{ entra_tenant_id }}/"
|
||||||
|
sso_url: "https://login.microsoftonline.com/{{ entra_tenant_id }}/saml2"
|
||||||
|
certificate: "{{ entra_certificate_path }}"
|
||||||
|
ldap:
|
||||||
|
url: "ldaps://ldap.example.com"
|
||||||
|
bind_dn: "cn=admin,dc=example,dc=com"
|
||||||
|
bind_credential: "changeme"
|
||||||
|
users_dn: "ou=Users,dc=example,dc=com"
|
||||||
|
groups_dn: "ou=Groups,dc=example,dc=com"
|
||||||
|
|
||||||
|
# 🔧 Step-CA Configuration
|
||||||
|
stepca_dns_names: "{{ domain_name }}"
|
||||||
|
stepca_admin_email: "{{ global_admin_email }}"
|
||||||
|
stepca_password: changeme-securely
|
||||||
|
|
||||||
|
# 🧑🔧 System User
|
||||||
|
svc_keycloak: svc_keycloak
|
||||||
|
svc_stepca: svc_stepca
|
||||||
|
|
||||||
|
stepca_enable_generate_root: true
|
||||||
|
stepca_root_cn: OpenCMMC Root CA
|
||||||
|
|
@ -1,12 +1,63 @@
|
||||||
---
|
---
|
||||||
- name: Restart keycloak
|
- name: Reload systemd and start keycloak
|
||||||
ansible.builtin.systemd:
|
systemd:
|
||||||
|
daemon_reload: true
|
||||||
name: keycloak
|
name: keycloak
|
||||||
state: restarted
|
state: restarted
|
||||||
enabled: true
|
enabled: true
|
||||||
|
|
||||||
- name: Restart step-ca
|
- name: Record evidence - keycloak service deployment
|
||||||
ansible.builtin.systemd:
|
copy:
|
||||||
name: step-ca
|
content: |
|
||||||
state: restarted
|
[Evidence] Keycloak systemd unit was deployed and restarted.
|
||||||
enabled: true
|
Timestamp: {{ ansible_date_time.iso8601 }}
|
||||||
|
dest: "{{ evidence_dir }}/01_identity_access/keycloak_service_deploy.log"
|
||||||
|
|
||||||
|
- name: Record evidence - step-ca container deployed
|
||||||
|
copy:
|
||||||
|
content: |
|
||||||
|
[Evidence] Step-CA container launched via Podman.
|
||||||
|
Timestamp: {{ ansible_date_time.iso8601 }}
|
||||||
|
dest: "{{ evidence_dir }}/01_identity_access/stepca_container.log"
|
||||||
|
|
||||||
|
- name: Record evidence - keycloak realm configured
|
||||||
|
copy:
|
||||||
|
content: |
|
||||||
|
[Evidence] Keycloak realm {{ keycloak_realm }} was successfully configured.
|
||||||
|
Timestamp: {{ ansible_date_time.iso8601 }}
|
||||||
|
dest: "{{ evidence_dir }}/01_identity_access/keycloak_realm_configured.log"
|
||||||
|
|
||||||
|
- name: Record evidence - SSO client integration
|
||||||
|
copy:
|
||||||
|
content: |
|
||||||
|
[Evidence] Nextcloud/Gitea SSO integration performed through Keycloak.
|
||||||
|
Timestamp: {{ ansible_date_time.iso8601 }}
|
||||||
|
dest: "{{ evidence_dir }}/01_identity_access/sso_client_integration.log"
|
||||||
|
|
||||||
|
- name: Record evidence - MFA flow enabled
|
||||||
|
copy:
|
||||||
|
content: |
|
||||||
|
[Evidence] Multi-factor authentication flow enabled in Keycloak.
|
||||||
|
Timestamp: {{ ansible_date_time.iso8601 }}
|
||||||
|
dest: "{{ evidence_dir }}/01_identity_access/keycloak_mfa_enabled.log"
|
||||||
|
|
||||||
|
- name: Save Step-CA certificate output to evidence log
|
||||||
|
copy:
|
||||||
|
content: "{{ stepca_cert_output.stdout }}"
|
||||||
|
dest: "evidence/01_identity_access/stepca_generated_certificates.log"
|
||||||
|
mode: "0644"
|
||||||
|
when: stepca_cert_output is defined
|
||||||
|
|
||||||
|
- name: Log issued Step-CA client certificates
|
||||||
|
copy:
|
||||||
|
content: |
|
||||||
|
{% for result in stepca_client_cert_output.results %}
|
||||||
|
CN: {{ result.item.common_name }}
|
||||||
|
Output:
|
||||||
|
{{ result.stdout | default('') }}
|
||||||
|
---
|
||||||
|
{% endfor %}
|
||||||
|
dest: "evidence/01_identity_access/stepca_client_certificates.log"
|
||||||
|
mode: "0644"
|
||||||
|
when: stepca_client_cert_output is defined
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,19 @@
|
||||||
|
# tasks/configure_realm.yml
|
||||||
---
|
---
|
||||||
|
- name: Wait for Keycloak to be ready
|
||||||
|
uri:
|
||||||
|
url: "http://localhost:{{ keycloak_port }}/realms/master"
|
||||||
|
method: GET
|
||||||
|
status_code: 200
|
||||||
|
register: keycloak_status
|
||||||
|
until: keycloak_status.status == 200
|
||||||
|
retries: 10
|
||||||
|
delay: 10
|
||||||
|
|
||||||
- name: Configure Keycloak realm and groups
|
- name: Configure Keycloak realm and groups
|
||||||
ansible.builtin.command:
|
command: >
|
||||||
cmd: "/opt/keycloak/bin/kcadm.sh create realms -s realm={{ keycloak_realm }} -s enabled=true"
|
/opt/keycloak/bin/kcadm.sh create realms -s realm={{ keycloak_realm }}
|
||||||
when: keycloak_realm is defined
|
-s enabled=true --server http://localhost:{{ keycloak_port }} --realm master
|
||||||
|
--user {{ keycloak_admin_user }} --password {{ keycloak_admin_password }}
|
||||||
|
args:
|
||||||
|
creates: "/opt/keycloak/realms/{{ keycloak_realm }}.configured"
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,14 @@
|
||||||
---
|
---
|
||||||
- name: Enroll clients in Step-CA
|
- name: Enroll client certificate
|
||||||
ansible.builtin.debug:
|
command: >
|
||||||
msg: "Provision client certificates using Step-CA"
|
step ca certificate
|
||||||
|
"{{ item.common_name }}"
|
||||||
|
"{{ item.cert_path }}"
|
||||||
|
"{{ item.key_path }}"
|
||||||
|
--provisioner "{{ item.provisioner }}"
|
||||||
|
--provisioner-password-file "{{ item.provisioner_password_file }}"
|
||||||
|
register: stepca_client_cert_output
|
||||||
|
loop: "{{ stepca_client_enrollments }}"
|
||||||
|
loop_control:
|
||||||
|
label: "{{ item.common_name }}"
|
||||||
|
notify: Log issued Step-CA client certificates
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
---
|
||||||
|
- name: Configure Entra ID SAML Identity Provider
|
||||||
|
when: enable_entra_federation
|
||||||
|
block:
|
||||||
|
- name: Create Entra ID SAML Identity Provider
|
||||||
|
ansible.builtin.command: >
|
||||||
|
{{ kcadm_bin }} create identity-provider/instances -r {{ keycloak_realm }}
|
||||||
|
-s alias=entra-id
|
||||||
|
-s providerId=saml
|
||||||
|
-s enabled=true
|
||||||
|
-s "config.samlEntityId={{ entra_saml_entity_id }}"
|
||||||
|
-s "config.singleSignOnServiceUrl={{ entra_sso_url }}"
|
||||||
|
-s "config.x509cert={{ entra_x509_cert }}"
|
||||||
|
environment:
|
||||||
|
PATH: "/opt/keycloak/bin:{{ ansible_env.PATH }}"
|
||||||
|
|
@ -1,4 +1,14 @@
|
||||||
---
|
---
|
||||||
- name: Generate CA certs using step-ca CLI
|
- name: Generate root certificate using step CLI
|
||||||
ansible.builtin.debug:
|
command: >
|
||||||
msg: "Running step ca init with preconfigured values"
|
step certificate create
|
||||||
|
--profile root-ca
|
||||||
|
--not-after=87600h
|
||||||
|
--password-file=/etc/step-ca/password.txt
|
||||||
|
"{{ stepca_root_cn }}"
|
||||||
|
/etc/step-ca/certs/root_ca.crt
|
||||||
|
/etc/step-ca/secrets/root_ca.key
|
||||||
|
register: stepca_cert_output
|
||||||
|
changed_when: "'certificates' in stepca_cert_output.stdout"
|
||||||
|
notify: Save Step-CA certificate output to evidence log
|
||||||
|
when: stepca_enable_generate_root | default(true)
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,23 @@
|
||||||
|
# tasks/install_keycloak.yml
|
||||||
---
|
---
|
||||||
- name: Install Keycloak container
|
- name: Create Keycloak data directory
|
||||||
containers.podman.podman_container:
|
file:
|
||||||
name: keycloak
|
path: "{{ keycloak_data_dir }}"
|
||||||
image: quay.io/keycloak/keycloak:{{ keycloak_version }}
|
state: directory
|
||||||
state: started
|
owner: "{{ svc_keycloak }}"
|
||||||
restart_policy: always
|
group: "{{ svc_keycloak }}"
|
||||||
env:
|
mode: '0755'
|
||||||
KEYCLOAK_ADMIN: "{{ keycloak_admin_user }}"
|
|
||||||
KEYCLOAK_ADMIN_PASSWORD: "{{ keycloak_admin_password }}"
|
- name: Render Keycloak podman-compose.yml
|
||||||
ports:
|
template:
|
||||||
- "8080:8080"
|
src: keycloak/podman-compose.yml.j2
|
||||||
|
dest: "{{ keycloak_data_dir }}/podman-compose.yml"
|
||||||
|
owner: "{{ svc_keycloak }}"
|
||||||
|
group: "{{ svc_keycloak }}"
|
||||||
|
mode: '0644'
|
||||||
|
|
||||||
|
- name: Render Keycloak systemd unit file
|
||||||
|
template:
|
||||||
|
src: keycloak/keycloak.service.j2
|
||||||
|
dest: "/etc/systemd/system/keycloak.service"
|
||||||
|
notify: Reload systemd and start keycloak
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,11 @@
|
||||||
|
# tasks/integrate_sso.yml
|
||||||
---
|
---
|
||||||
- name: Setup OIDC clients for SSO integration
|
- name: Register Nextcloud client in Keycloak
|
||||||
ansible.builtin.debug:
|
command: >
|
||||||
msg: "Configure OIDC clients for Mailcow, Gitea and SAML for Nextcloud"
|
/opt/keycloak/bin/kcadm.sh create clients -r {{ keycloak_realm }}
|
||||||
|
-s clientId=nextcloud -s enabled=true
|
||||||
|
-s protocol=saml
|
||||||
|
--server http://localhost:{{ keycloak_port }}
|
||||||
|
--realm master
|
||||||
|
--user {{ keycloak_admin_user }} --password {{ keycloak_admin_password }}
|
||||||
|
when: sso_nextcloud is defined
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
---
|
||||||
|
- name: Configure LDAP Federation
|
||||||
|
when: enable_ldap_federation
|
||||||
|
block:
|
||||||
|
- name: Create LDAP provider
|
||||||
|
ansible.builtin.command: >
|
||||||
|
{{ kcadm_bin }} create user-storage/ldap -r {{ keycloak_realm }}
|
||||||
|
-s name=ldap-users
|
||||||
|
-s providerId=ldap
|
||||||
|
-s enabled=true
|
||||||
|
-s "config.connectionUrl={{ ldap_url }}"
|
||||||
|
-s "config.bindDn={{ ldap_bind_dn }}"
|
||||||
|
-s "config.bindCredential={{ ldap_bind_password }}"
|
||||||
|
-s "config.usersDn={{ ldap_user_search_base }}"
|
||||||
|
-s "config.groupsDn={{ ldap_group_search_base }}"
|
||||||
|
-s "config.editMode=READ_ONLY"
|
||||||
|
-s "config.syncRegistrations=false"
|
||||||
|
environment:
|
||||||
|
PATH: "/opt/keycloak/bin:{{ ansible_env.PATH }}"
|
||||||
|
|
@ -1,21 +1,23 @@
|
||||||
---
|
---
|
||||||
- name: Include tasks to install and configure Keycloak
|
# tasks/main.yml - Identity Role Orchestration
|
||||||
|
|
||||||
|
- name: Install and configure Keycloak
|
||||||
include_tasks: install_keycloak.yml
|
include_tasks: install_keycloak.yml
|
||||||
|
|
||||||
- name: Include tasks to configure realm and users
|
- name: Configure Keycloak realm, groups, and users
|
||||||
include_tasks: configure_realm.yml
|
include_tasks: configure_realm.yml
|
||||||
|
|
||||||
- name: Include tasks to setup SSO integration
|
- name: Integrate SSO with registered services (Nextcloud, Mailcow, etc.)
|
||||||
include_tasks: integrate_sso.yml
|
include_tasks: integrate_sso.yml
|
||||||
|
|
||||||
- name: Include tasks to configure MFA policies
|
- name: Apply MFA enforcement policies
|
||||||
include_tasks: setup_mfa.yml
|
include_tasks: setup_mfa.yml
|
||||||
|
|
||||||
- name: Include tasks to provision Step-CA
|
- name: Provision Step-CA container and config
|
||||||
include_tasks: provision_step_ca.yml
|
include_tasks: provision_step_ca.yml
|
||||||
|
|
||||||
- name: Include tasks to enroll clients in Step-CA
|
- name: Enroll default internal clients into Step-CA
|
||||||
include_tasks: enroll_clients.yml
|
include_tasks: enroll_clients.yml
|
||||||
|
|
||||||
- name: Include tasks to generate CA certificates
|
- name: Generate initial CA root and intermediate certificates
|
||||||
include_tasks: generate_ca_certs.yml
|
include_tasks: generate_ca_certs.yml
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,24 @@
|
||||||
|
# tasks/provision_step_ca.yml
|
||||||
---
|
---
|
||||||
- name: Install step-ca and create systemd service
|
- name: Create Step-CA data directory
|
||||||
ansible.builtin.copy:
|
file:
|
||||||
src: systemd-step-ca.service.j2
|
path: "{{ stepca_data_dir }}"
|
||||||
dest: /etc/systemd/system/step-ca.service
|
state: directory
|
||||||
notify: Restart step-ca
|
owner: "{{ svc_stepca }}"
|
||||||
|
group: "{{ svc_stepca }}"
|
||||||
|
mode: '0755'
|
||||||
|
|
||||||
|
- name: Deploy Step-CA container with Podman
|
||||||
|
containers.podman.podman_container:
|
||||||
|
name: step-ca
|
||||||
|
image: smallstep/step-ca:latest
|
||||||
|
state: started
|
||||||
|
restart_policy: always
|
||||||
|
ports:
|
||||||
|
- "{{ stepca_port }}:9000"
|
||||||
|
volumes:
|
||||||
|
- "{{ stepca_data_dir }}:/home/step"
|
||||||
|
env:
|
||||||
|
STEPCA_PASSWORD: "{{ stepca_password }}"
|
||||||
|
STEPCA_ADMIN_EMAIL: "{{ global_admin_email }}"
|
||||||
|
STEPCA_DNS_NAMES: "{{ domain_name }}"
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,10 @@
|
||||||
|
# tasks/setup_mfa.yml
|
||||||
---
|
---
|
||||||
- name: Enable MFA for users
|
- name: Enable MFA flow in Keycloak
|
||||||
ansible.builtin.debug:
|
command: >
|
||||||
msg: "Enabling TOTP in Keycloak authentication flow"
|
/opt/keycloak/bin/kcadm.sh update authentication/flows/browser
|
||||||
|
-r {{ keycloak_realm }}
|
||||||
|
-s 'requireMFA=true'
|
||||||
|
--server http://localhost:{{ keycloak_port }}
|
||||||
|
--realm master
|
||||||
|
--user {{ keycloak_admin_user }} --password {{ keycloak_admin_password }}
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,22 @@
|
||||||
---
|
---
|
||||||
# Reserved for any future log restart triggers or alert changes
|
- name: Document Monitoring Deployment (Wazuh)
|
||||||
|
copy:
|
||||||
|
content: |
|
||||||
|
# ✅ Wazuh Monitoring and Alerting
|
||||||
|
|
||||||
|
This deployment configured endpoint and container monitoring using:
|
||||||
|
|
||||||
|
- Wazuh server container
|
||||||
|
- Log forwarding and indexing
|
||||||
|
- Preconfigured alert rules
|
||||||
|
|
||||||
|
The system now supports real-time alerting, intrusion detection, and compliance monitoring.
|
||||||
|
dest: "{{ evidence_base_dir | default('evidence') }}/05_monitoring/monitoring_summary.md"
|
||||||
|
mode: '0644'
|
||||||
|
|
||||||
|
- name: Archive monitoring logs
|
||||||
|
copy:
|
||||||
|
src: /tmp/monitoring_run.log
|
||||||
|
dest: "{{ evidence_base_dir | default('evidence') }}/05_monitoring/monitoring_run.log"
|
||||||
|
remote_src: yes
|
||||||
|
mode: '0644'
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,51 @@
|
||||||
---
|
---
|
||||||
# Reserved for future restarts
|
- name: Document Podman Services Deployment
|
||||||
|
copy:
|
||||||
|
content: |
|
||||||
|
# ✅ Podman Services Deployed
|
||||||
|
|
||||||
|
This summary confirms successful deployment of core containerized services using Podman:
|
||||||
|
|
||||||
|
- Keycloak, Mailcow, Wazuh, and Step-CA launched via systemd-managed Podman containers
|
||||||
|
- All services use rootless accounts and secured volumes
|
||||||
|
- podman-compose and systemd integration verified
|
||||||
|
- Service logs and container health validated
|
||||||
|
|
||||||
|
These services satisfy a wide set of CMMC controls including AC, SC, IA, AU, and CM families.
|
||||||
|
dest: "{{ evidence_base_dir | default('evidence') }}/04_platform_services/podman_services_summary.md"
|
||||||
|
mode: '0644'
|
||||||
|
|
||||||
|
- name: Archive podman_services logs
|
||||||
|
copy:
|
||||||
|
src: /tmp/podman_services_run.log
|
||||||
|
dest: "{{ evidence_base_dir | default('evidence') }}/04_platform_services/podman_services_run.log"
|
||||||
|
remote_src: yes
|
||||||
|
mode: '0644'
|
||||||
|
|
||||||
|
- name: Document Step-CA Deployment
|
||||||
|
copy:
|
||||||
|
content: |
|
||||||
|
# Step-CA Deployment Log
|
||||||
|
|
||||||
|
Step-CA was successfully deployed and enabled as a system service.
|
||||||
|
|
||||||
|
- Timestamp: {{ ansible_date_time.iso8601 }}
|
||||||
|
- User: {{ ansible_user }}
|
||||||
|
- Container Image: smallstep/step-ca:latest
|
||||||
|
- Port: {{ stepca_port }}
|
||||||
|
|
||||||
|
dest: "{{ evidence_dir }}/01_identity_access/step-ca_summary.md"
|
||||||
|
mode: "0644"
|
||||||
|
|
||||||
|
- name: Archive Step-CA Logs
|
||||||
|
shell: |
|
||||||
|
journalctl -u step-ca > {{ evidence_dir }}/01_identity_access/step-ca_run.log
|
||||||
|
args:
|
||||||
|
executable: /bin/bash
|
||||||
|
|
||||||
|
- name: Log Mailcow provisioning
|
||||||
|
copy:
|
||||||
|
content: "Mailcow deployed successfully at {{ ansible_date_time.iso8601 }}"
|
||||||
|
dest: "evidence/04_email/mailcow_deploy.log"
|
||||||
|
mode: '0644'
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,41 @@
|
||||||
|
---
|
||||||
|
- name: Ensure Keycloak data directory exists
|
||||||
|
file:
|
||||||
|
path: "{{ keycloak_data_dir }}"
|
||||||
|
state: directory
|
||||||
|
owner: "{{ svc_keycloak }}"
|
||||||
|
group: "{{ svc_keycloak }}"
|
||||||
|
mode: "0755"
|
||||||
|
|
||||||
|
- name: Pull Keycloak image
|
||||||
|
containers.podman.podman_image:
|
||||||
|
name: "{{ keycloak_image }}"
|
||||||
|
|
||||||
|
- name: Create Keycloak container
|
||||||
|
containers.podman.podman_container:
|
||||||
|
name: keycloak
|
||||||
|
image: "{{ keycloak_image }}"
|
||||||
|
state: started
|
||||||
|
restart_policy: always
|
||||||
|
user: "{{ svc_keycloak }}"
|
||||||
|
ports:
|
||||||
|
- "{{ keycloak_port }}:8080"
|
||||||
|
env:
|
||||||
|
KEYCLOAK_ADMIN: "{{ keycloak_admin_user }}"
|
||||||
|
KEYCLOAK_ADMIN_PASSWORD: "{{ keycloak_admin_password }}"
|
||||||
|
volumes:
|
||||||
|
- "{{ keycloak_data_dir }}:/opt/keycloak/data:z"
|
||||||
|
command:
|
||||||
|
- "start"
|
||||||
|
- "--optimized"
|
||||||
|
|
||||||
|
- name: Copy systemd unit template for Keycloak
|
||||||
|
template:
|
||||||
|
src: keycloak.service.j2
|
||||||
|
dest: "/etc/systemd/system/keycloak.service"
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: "0644"
|
||||||
|
notify:
|
||||||
|
- Reload systemd
|
||||||
|
- Enable and start Keycloak
|
||||||
|
|
@ -1,38 +1,44 @@
|
||||||
---
|
---
|
||||||
- name: Deploy step_ca container with Podman
|
- name: Ensure Step-CA data directory exists
|
||||||
containers.podman.podman_container:
|
file:
|
||||||
name: step_ca
|
path: "{{ stepca_data_dir }}"
|
||||||
image: "{{ step_ca_image }}"
|
state: directory
|
||||||
state: started
|
owner: "{{ svc_stepca }}"
|
||||||
restart_policy: always
|
group: "{{ svc_stepca }}"
|
||||||
volumes:
|
mode: "0750"
|
||||||
- "{{ step_ca_data_dir }}:/data:z"
|
|
||||||
env:
|
|
||||||
CONFIG_PATH: "/data/config"
|
|
||||||
|
|
||||||
- name: Ensure systemd service is enabled for step_ca
|
- name: Template Step-CA podman-compose.yml
|
||||||
copy:
|
template:
|
||||||
dest: "/etc/systemd/system/podman-step_ca.service"
|
src: step_ca/podman-compose.yml.j2
|
||||||
content: |
|
dest: "{{ stepca_data_dir }}/podman-compose.yml"
|
||||||
[Unit]
|
owner: "{{ svc_stepca }}"
|
||||||
Description=Podman container for step_ca
|
group: "{{ svc_stepca }}"
|
||||||
Wants=network.target
|
|
||||||
After=network.target
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
ExecStart=/usr/bin/podman start -a step_ca
|
|
||||||
ExecStop=/usr/bin/podman stop -t 10 step_ca
|
|
||||||
Restart=always
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target
|
|
||||||
owner: root
|
|
||||||
group: root
|
|
||||||
mode: "0644"
|
mode: "0644"
|
||||||
|
|
||||||
- name: Reload systemd and enable service for step_ca
|
- name: Template Step-CA systemd unit file
|
||||||
|
template:
|
||||||
|
src: step_ca/step-ca.service.j2
|
||||||
|
dest: "/etc/systemd/system/step-ca.service"
|
||||||
|
mode: "0644"
|
||||||
|
|
||||||
|
- name: Template Step-CA environment file
|
||||||
|
template:
|
||||||
|
src: step_ca/.env.j2
|
||||||
|
dest: "{{ stepca_data_dir }}/.env"
|
||||||
|
owner: "{{ svc_stepca }}"
|
||||||
|
group: "{{ svc_stepca }}"
|
||||||
|
mode: "0600"
|
||||||
|
|
||||||
|
- name: Reload systemd and enable Step-CA
|
||||||
systemd:
|
systemd:
|
||||||
daemon_reload: yes
|
name: step-ca
|
||||||
name: podman-step_ca.service
|
enabled: true
|
||||||
enabled: yes
|
daemon_reload: true
|
||||||
state: started
|
state: restarted
|
||||||
|
|
||||||
|
- name: Log deployment for Step-CA
|
||||||
|
debug:
|
||||||
|
msg: "Step-CA deployment complete"
|
||||||
|
notify:
|
||||||
|
- Document Step-CA Deployment
|
||||||
|
- Archive Step-CA Logs
|
||||||
|
|
|
||||||
|
|
@ -1,38 +1,37 @@
|
||||||
---
|
---
|
||||||
- name: Deploy wazuh container with Podman
|
- name: Ensure Wazuh data directory exists
|
||||||
containers.podman.podman_container:
|
file:
|
||||||
name: wazuh
|
path: "{{ wazuh_data_dir | default('/opt/wazuh') }}"
|
||||||
image: "{{ wazuh_image }}"
|
state: directory
|
||||||
state: started
|
owner: "{{ svc_wazuh }}"
|
||||||
restart_policy: always
|
group: "{{ svc_wazuh }}"
|
||||||
volumes:
|
mode: '0755'
|
||||||
- "{{ wazuh_data_dir }}:/data:z"
|
|
||||||
env:
|
|
||||||
CONFIG_PATH: "/data/config"
|
|
||||||
|
|
||||||
- name: Ensure systemd service is enabled for wazuh
|
- name: Deploy wazuh.env file
|
||||||
copy:
|
template:
|
||||||
|
src: wazuh/.env.j2
|
||||||
|
dest: "{{ wazuh_data_dir }}/.env"
|
||||||
|
owner: "{{ svc_wazuh }}"
|
||||||
|
group: "{{ svc_wazuh }}"
|
||||||
|
mode: '0640'
|
||||||
|
|
||||||
|
- name: Deploy Wazuh podman-compose file
|
||||||
|
template:
|
||||||
|
src: wazuh/podman-compose.yml.j2
|
||||||
|
dest: "{{ wazuh_data_dir }}/podman-compose.yml"
|
||||||
|
owner: "{{ svc_wazuh }}"
|
||||||
|
group: "{{ svc_wazuh }}"
|
||||||
|
mode: '0644'
|
||||||
|
|
||||||
|
- name: Deploy Wazuh systemd unit
|
||||||
|
template:
|
||||||
|
src: wazuh/wazuh.service.j2
|
||||||
dest: "/etc/systemd/system/podman-wazuh.service"
|
dest: "/etc/systemd/system/podman-wazuh.service"
|
||||||
content: |
|
mode: '0644'
|
||||||
[Unit]
|
|
||||||
Description=Podman container for wazuh
|
|
||||||
Wants=network.target
|
|
||||||
After=network.target
|
|
||||||
|
|
||||||
[Service]
|
- name: Reload systemd and enable wazuh
|
||||||
ExecStart=/usr/bin/podman start -a wazuh
|
|
||||||
ExecStop=/usr/bin/podman stop -t 10 wazuh
|
|
||||||
Restart=always
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target
|
|
||||||
owner: root
|
|
||||||
group: root
|
|
||||||
mode: "0644"
|
|
||||||
|
|
||||||
- name: Reload systemd and enable service for wazuh
|
|
||||||
systemd:
|
systemd:
|
||||||
daemon_reload: yes
|
daemon_reload: true
|
||||||
name: podman-wazuh.service
|
name: podman-wazuh
|
||||||
enabled: yes
|
enabled: true
|
||||||
state: started
|
state: started
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
[Unit]
|
||||||
|
Description=Podman container for Keycloak (OpenCMMC Identity)
|
||||||
|
Wants=network.target
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
User={{ svc_keycloak }}
|
||||||
|
ExecStart=/usr/bin/podman start -a keycloak
|
||||||
|
ExecStop=/usr/bin/podman stop -t 10 keycloak
|
||||||
|
Restart=always
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
STEPCA_PASSWORD={{ stepca_password }}
|
||||||
|
STEPCA_DNS_NAMES={{ domain_name }}
|
||||||
|
STEPCA_ADMIN_EMAIL={{ global_admin_email }}
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
version: "3.8"
|
||||||
|
services:
|
||||||
|
stepca:
|
||||||
|
image: smallstep/step-ca:latest
|
||||||
|
container_name: step-ca
|
||||||
|
restart: always
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
ports:
|
||||||
|
- "{{ stepca_port }}:9000"
|
||||||
|
volumes:
|
||||||
|
- "{{ stepca_data_dir }}/certs:/home/step/certs"
|
||||||
|
- "{{ stepca_data_dir }}/config:/home/step/config"
|
||||||
|
user: "{{ svc_stepca }}"
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
[Unit]
|
||||||
|
Description=Step-CA Certificate Authority Service
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
ExecStart=/usr/bin/podman-compose -f {{ stepca_data_dir }}/podman-compose.yml up
|
||||||
|
ExecStop=/usr/bin/podman-compose -f {{ stepca_data_dir }}/podman-compose.yml down
|
||||||
|
Restart=always
|
||||||
|
User={{ svc_stepca }}
|
||||||
|
WorkingDirectory={{ stepca_data_dir }}
|
||||||
|
EnvironmentFile={{ stepca_data_dir }}/.env
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
WAZUH_VERSION=4.7.3
|
||||||
|
WAZUH_PASSWORD={{ wazuh_admin_password | default('ChangeMeSecurely') }}
|
||||||
|
CLUSTER_NAME=opencmmc-cluster
|
||||||
|
NODE_NAME=wazuh-manager
|
||||||
|
ELASTICSEARCH_URL=https://localhost:9200
|
||||||
|
KIBANA_URL=https://localhost:5601
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
version: '3.8'
|
||||||
|
services:
|
||||||
|
wazuh:
|
||||||
|
image: wazuh/wazuh-manager:{{ wazuh_version | default('4.7.3') }}
|
||||||
|
container_name: wazuh-manager
|
||||||
|
restart: always
|
||||||
|
ports:
|
||||||
|
- "{{ wazuh_port }}:55000"
|
||||||
|
volumes:
|
||||||
|
- "{{ wazuh_data_dir }}/data:/var/ossec/data"
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
[Unit]
|
||||||
|
Description=Podman Container for Wazuh Manager
|
||||||
|
Wants=network-online.target
|
||||||
|
After=network-online.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
User={{ svc_wazuh }}
|
||||||
|
Group={{ svc_wazuh }}
|
||||||
|
EnvironmentFile=-/opt/services/wazuh/.env
|
||||||
|
ExecStart=/usr/bin/podman-compose -f /opt/services/wazuh/podman-compose.yml up
|
||||||
|
ExecStop=/usr/bin/podman-compose -f /opt/services/wazuh/podman-compose.yml down
|
||||||
|
Restart=always
|
||||||
|
TimeoutStartSec=0
|
||||||
|
SyslogIdentifier=wazuh
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
---
|
||||||
|
- name: Document Preflight Validation Results
|
||||||
|
copy:
|
||||||
|
content: |
|
||||||
|
# ✅ Preflight Deployment Validation
|
||||||
|
|
||||||
|
Preflight checks completed successfully before provisioning and configuration:
|
||||||
|
|
||||||
|
- `deployment_config.yml` parsed and validated
|
||||||
|
- Required fields present and formatted
|
||||||
|
- DNS resolver availability confirmed
|
||||||
|
- Admin SSH key and email syntax verified
|
||||||
|
- Ports and directories validated
|
||||||
|
- Infrastructure provider settings validated
|
||||||
|
|
||||||
|
All conditions passed, greenlight for infrastructure deployment.
|
||||||
|
dest: "{{ evidence_base_dir | default('evidence') }}/08_preflight_checks/preflight_summary.md"
|
||||||
|
mode: '0644'
|
||||||
|
|
||||||
|
- name: Archive preflight logs
|
||||||
|
copy:
|
||||||
|
src: /tmp/preflight_run.log
|
||||||
|
dest: "{{ evidence_base_dir | default('evidence') }}/08_preflight_checks/preflight_run.log"
|
||||||
|
remote_src: yes
|
||||||
|
mode: '0644'
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
- name: Check if 'stepca_password' is defined
|
||||||
|
fail:
|
||||||
|
msg: "'stepca_password' is not defined in group_vars or deployment_config."
|
||||||
|
when: stepca_password is not defined
|
||||||
|
|
||||||
|
- name: Check if 'svc_stepca' user is defined
|
||||||
|
fail:
|
||||||
|
msg: "'svc_stepca' system user is not defined."
|
||||||
|
when: svc_stepca is not defined
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
---
|
||||||
|
- name: Ensure MOTD file is present
|
||||||
|
copy:
|
||||||
|
content: "{{ motd_banner_text }}"
|
||||||
|
dest: /etc/motd
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: '0644'
|
||||||
|
when: motd_banner_text is defined
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
*** WELCOME TO {{ domain_name | default('this system') }} ***
|
||||||
|
|
||||||
|
Unauthorized use is prohibited and may be monitored.
|
||||||
|
This system is protected under CMMC Level 2 security policies.
|
||||||
|
|
||||||
|
All activity is logged and may be disclosed to authorized personnel.
|
||||||
|
Users must comply with all company policies and procedures.
|
||||||
|
|
||||||
|
{{ motd_custom_note | default('') }}
|
||||||
|
|
@ -19,6 +19,8 @@ region: nyc3
|
||||||
vm_size: s-2vcpu-4gb
|
vm_size: s-2vcpu-4gb
|
||||||
|
|
||||||
# 🔐 Security Parameters
|
# 🔐 Security Parameters
|
||||||
|
motd_banner_text: "{{ lookup('template', 'roles/secure_ubuntu/templates/motd.txt.j2') }}"
|
||||||
|
|
||||||
banner_text: |
|
banner_text: |
|
||||||
*** WARNING ***
|
*** WARNING ***
|
||||||
|
|
||||||
|
|
@ -45,6 +47,8 @@ tailscale_auth_key: tskey-abc123
|
||||||
|
|
||||||
# 📜 Keycloak Identity Settings
|
# 📜 Keycloak Identity Settings
|
||||||
keycloak_realm: OpenCMMC
|
keycloak_realm: OpenCMMC
|
||||||
|
keycloak_admin_user: admin
|
||||||
|
keycloak_admin_password: change_me_securely
|
||||||
|
|
||||||
# 🛡️ Ports Used by Services
|
# 🛡️ Ports Used by Services
|
||||||
nextcloud_port: 8080
|
nextcloud_port: 8080
|
||||||
|
|
@ -73,3 +77,6 @@ svc_keycloak: svc_keycloak
|
||||||
svc_mailcow: svc_mailcow
|
svc_mailcow: svc_mailcow
|
||||||
svc_wazuh: svc_wazuh
|
svc_wazuh: svc_wazuh
|
||||||
svc_stepca: svc_stepca
|
svc_stepca: svc_stepca
|
||||||
|
|
||||||
|
# 🔐 Step-CA Settings
|
||||||
|
stepca_password: changeme-securely
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
# Step-CA Deployment Summary
|
||||||
|
|
||||||
|
Initial deployment successful.
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
# 📧 Mailcow Deployment Evidence
|
||||||
|
|
||||||
|
This file contains the output and verification logs for the deployment of the Mailcow secure email platform as part of the OpenCMMC Stack.
|
||||||
|
|
||||||
|
## ✅ Deployment Log
|
||||||
|
|
||||||
|
Refer to `mailcow_deploy.log` for timestamped deployment confirmation from the Ansible run.
|
||||||
|
|
||||||
|
## 🔍 Verification Checklist
|
||||||
|
|
||||||
|
- [x] Mailcow container is running (`podman ps`)
|
||||||
|
- [x] mailcow.service is active (`systemctl status`)
|
||||||
|
- [x] /opt/mailcow directory is present and owned correctly
|
||||||
|
|
||||||
|
This service is containerized via Podman, proxied via NGINX, and restricted with Zero Trust ACLs.
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
# Sanitized Example: Wazuh Configuration Variables
|
||||||
|
WAZUH_PASSWORD=admin
|
||||||
|
|
@ -1,50 +1,99 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
generate_group_vars.py – Converts deployment_config.yml into Ansible group_vars/all.yml
|
||||||
|
Author: OpenCMMC Stack Automation
|
||||||
|
"""
|
||||||
|
|
||||||
import yaml
|
import yaml
|
||||||
|
from pathlib import Path
|
||||||
|
import sys
|
||||||
|
|
||||||
# Load deployment_config.yml
|
CONFIG_FILE = "deployment_config.yml"
|
||||||
with open('deployment_config.yml', 'r') as f:
|
OUTPUT_FILE = "group_vars/all.yml"
|
||||||
deployment_config = yaml.safe_load(f)
|
|
||||||
|
|
||||||
# Flattened structure for group_vars/all.yml
|
REQUIRED_FIELDS = [
|
||||||
group_vars = {
|
"global_admin_username", "admin_ssh_public_key", "domain_name",
|
||||||
'default_user': deployment_config['global_admin_username'],
|
"hostname", "nextcloud_port", "mailcow_port", "keycloak_port",
|
||||||
'default_shell': '/bin/bash',
|
"keycloak_image", "nextcloud_aio_image", "mailcow_image"
|
||||||
'ssh_authorized_key': deployment_config['admin_ssh_public_key'],
|
]
|
||||||
'global_admin_email': deployment_config['global_admin_email'],
|
|
||||||
'domain_name': deployment_config['domain_name'],
|
|
||||||
'hostname': deployment_config['hostname'],
|
|
||||||
'timezone': deployment_config['timezone'],
|
|
||||||
'dns_resolver_ip': deployment_config['dns_resolver_ip'],
|
|
||||||
'ssh_port': deployment_config['ssh_port'],
|
|
||||||
'disable_root_ssh': deployment_config['disable_root_ssh'],
|
|
||||||
'enforce_key_authentication': deployment_config['enforce_key_authentication'],
|
|
||||||
'nextcloud_port': deployment_config['nextcloud_port'],
|
|
||||||
'mailcow_port': deployment_config['mailcow_port'],
|
|
||||||
'keycloak_port': deployment_config['keycloak_port'],
|
|
||||||
'stepca_port': deployment_config['stepca_port'],
|
|
||||||
'wazuh_port': deployment_config['wazuh_port'],
|
|
||||||
'tailscale_auth_key': deployment_config['tailscale_auth_key'],
|
|
||||||
'mailcow_hostname': deployment_config['mailcow_hostname'],
|
|
||||||
'mailcow_admin_user': deployment_config['mailcow_admin_user'],
|
|
||||||
'mailcow_admin_password': deployment_config['mailcow_admin_password'],
|
|
||||||
'mailcow_letsencrypt_email': deployment_config['mailcow_letsencrypt_email'],
|
|
||||||
'mailcow_use_letsencrypt': deployment_config['mailcow_use_letsencrypt'],
|
|
||||||
'keycloak_realm': deployment_config['keycloak_realm'],
|
|
||||||
'nextcloud_aio_image': deployment_config['nextcloud_aio_image'],
|
|
||||||
'keycloak_image': deployment_config['keycloak_image'],
|
|
||||||
'mailcow_image': deployment_config['mailcow_image'],
|
|
||||||
'nextcloud_data_dir': deployment_config['nextcloud_data_dir'],
|
|
||||||
'mailcow_data_dir': deployment_config['mailcow_data_dir'],
|
|
||||||
'backup_base_dir': deployment_config['backup_base_dir'],
|
|
||||||
'logs_dir': deployment_config['logs_dir'],
|
|
||||||
'restic_password': deployment_config['restic_password'],
|
|
||||||
'restic_repo': deployment_config['restic_repo'],
|
|
||||||
'svc_keycloak': deployment_config['svc_keycloak'],
|
|
||||||
'svc_mailcow': deployment_config['svc_mailcow'],
|
|
||||||
'svc_wazuh': deployment_config['svc_wazuh'],
|
|
||||||
'svc_stepca': deployment_config['svc_stepca'],
|
|
||||||
'banner_text': deployment_config['banner_text']
|
|
||||||
}
|
|
||||||
|
|
||||||
# Save to group_vars/all.yml
|
def load_config():
|
||||||
with open('group_vars/all.yml', 'w') as f:
|
if not Path(CONFIG_FILE).exists():
|
||||||
yaml.dump(group_vars, f, sort_keys=False, default_flow_style=False)
|
sys.exit(f"[!] {CONFIG_FILE} not found.")
|
||||||
|
with open(CONFIG_FILE, "r") as f:
|
||||||
|
return yaml.safe_load(f)
|
||||||
|
|
||||||
|
def validate_config(cfg):
|
||||||
|
missing = [key for key in REQUIRED_FIELDS if key not in cfg]
|
||||||
|
if missing:
|
||||||
|
sys.exit(f"[!] Missing required keys in {CONFIG_FILE}: {', '.join(missing)}")
|
||||||
|
|
||||||
|
def build_output(cfg):
|
||||||
|
return {
|
||||||
|
# Global User
|
||||||
|
"default_user": cfg["global_admin_username"],
|
||||||
|
"default_shell": "/bin/bash",
|
||||||
|
"ssh_authorized_key": cfg["admin_ssh_public_key"],
|
||||||
|
|
||||||
|
# System Info
|
||||||
|
"domain_name": cfg["domain_name"],
|
||||||
|
"hostname": cfg["hostname"],
|
||||||
|
"timezone": cfg.get("timezone", "UTC"),
|
||||||
|
"dns_resolver_ip": cfg.get("dns_resolver_ip", "1.1.1.1"),
|
||||||
|
|
||||||
|
# Network Ports
|
||||||
|
"nextcloud_port": cfg["nextcloud_port"],
|
||||||
|
"mailcow_port": cfg["mailcow_port"],
|
||||||
|
"keycloak_port": cfg["keycloak_port"],
|
||||||
|
"stepca_port": cfg.get("stepca_port", 9000),
|
||||||
|
"wazuh_port": cfg.get("wazuh_port", 55000),
|
||||||
|
|
||||||
|
# Container Images
|
||||||
|
"nextcloud_aio_image": cfg["nextcloud_aio_image"],
|
||||||
|
"keycloak_image": cfg["keycloak_image"],
|
||||||
|
"mailcow_image": cfg["mailcow_image"],
|
||||||
|
|
||||||
|
# Paths
|
||||||
|
"nextcloud_data_dir": cfg.get("nextcloud_data_dir", "/srv/nextcloud"),
|
||||||
|
"mailcow_data_dir": cfg.get("mailcow_data_dir", "/opt/mailcow"),
|
||||||
|
"backup_base_dir": cfg.get("backup_base_dir", "/srv/backups"),
|
||||||
|
"logs_dir": cfg.get("logs_dir", "/var/log/open-cmmc"),
|
||||||
|
|
||||||
|
# System Accounts
|
||||||
|
"svc_keycloak": cfg.get("svc_keycloak", "svc_keycloak"),
|
||||||
|
"svc_mailcow": cfg.get("svc_mailcow", "svc_mailcow"),
|
||||||
|
"svc_wazuh": cfg.get("svc_wazuh", "svc_wazuh"),
|
||||||
|
"svc_stepca": cfg.get("svc_stepca", "svc_stepca"),
|
||||||
|
|
||||||
|
# Backup
|
||||||
|
"restic_password": cfg.get("restic_password", "changeme-securely"),
|
||||||
|
"restic_repo": cfg.get("restic_repo", "/srv/backups/restic-repo"),
|
||||||
|
|
||||||
|
# Mailcow
|
||||||
|
"mailcow_hostname": cfg.get("mailcow_hostname", "mail"),
|
||||||
|
"mailcow_fqdn": f"{cfg.get('mailcow_hostname', 'mail')}.{cfg['domain_name']}",
|
||||||
|
"mailcow_admin_user": cfg.get("mailcow_admin_user", "admin"),
|
||||||
|
"mailcow_admin_password": cfg.get("mailcow_admin_password", "changeme"),
|
||||||
|
"mailcow_letsencrypt_email": cfg.get("mailcow_letsencrypt_email", "admin@localhost"),
|
||||||
|
"mailcow_use_letsencrypt": cfg.get("mailcow_use_letsencrypt", "n"),
|
||||||
|
|
||||||
|
# SSO & VPN
|
||||||
|
"tailscale_auth_key": cfg.get("tailscale_auth_key", ""),
|
||||||
|
"keycloak_realm": cfg.get("keycloak_realm", "OpenCMMC"),
|
||||||
|
"keycloak_admin_user": cfg.get("keycloak_admin_user", "admin"),
|
||||||
|
"keycloak_admin_password": cfg.get("keycloak_admin_password", "changeme"),
|
||||||
|
}
|
||||||
|
|
||||||
|
def main():
|
||||||
|
config = load_config()
|
||||||
|
validate_config(config)
|
||||||
|
output = build_output(config)
|
||||||
|
|
||||||
|
Path("group_vars").mkdir(parents=True, exist_ok=True)
|
||||||
|
with open(OUTPUT_FILE, "w") as f:
|
||||||
|
yaml.dump(output, f, sort_keys=False, default_flow_style=False)
|
||||||
|
|
||||||
|
print(f"[✓] {OUTPUT_FILE} generated successfully from {CONFIG_FILE}")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue