294 lines
11 KiB
YAML
294 lines
11 KiB
YAML
---
|
|
# Deploy and configure Single Node OpenShift (SNO) on Proxmox
|
|
#
|
|
# Prerequisites:
|
|
# ansible-galaxy collection install -r collections/requirements.yml
|
|
# openshift-install is downloaded automatically during the sno_deploy_install play
|
|
#
|
|
# Inventory requirements:
|
|
# sno.openshift.toal.ca - in 'openshift' group
|
|
# host_vars: ocp_cluster_name, ocp_base_domain, ocp_version, sno_ip,
|
|
# sno_gateway, sno_nameserver, sno_prefix_length, sno_vm_name,
|
|
# sno_bridge, sno_vlan, proxmox_node, keycloak_url, keycloak_realm,
|
|
# oidc_admin_groups, sno_deploy_letsencrypt_email, ...
|
|
# secrets: vault_ocp_pull_secret, vault_keycloak_admin_password,
|
|
# vault_oidc_client_secret (optional)
|
|
# proxmox_api - inventory host (ansible_host, ansible_port)
|
|
# proxmox_host - inventory host (ansible_host, ansible_connection: ssh)
|
|
# gate.toal.ca - in 'opnsense' group
|
|
# host_vars: opnsense_host, opnsense_api_key, opnsense_api_secret,
|
|
# opnsense_api_port, haproxy_public_ip
|
|
# group_vars/all: dme_account_key, dme_account_secret
|
|
#
|
|
# Play order (intentional — DNS must precede VM boot):
|
|
# Play 1: sno_deploy_vm — Create SNO VM
|
|
# Play 2: opnsense — Configure OPNsense local DNS overrides
|
|
# Play 3: dns — Configure public DNS records in DNS Made Easy
|
|
# Play 4: sno_deploy_install — Generate ISO, boot VM, wait for install
|
|
# Play 5: keycloak — Configure Keycloak OIDC client
|
|
# Play 6: sno_deploy_oidc / sno_deploy_certmanager / sno_deploy_delete_kubeadmin
|
|
#
|
|
# Usage:
|
|
# ansible-navigator run playbooks/deploy_openshift.yml
|
|
# ansible-navigator run playbooks/deploy_openshift.yml --tags sno_deploy_vm
|
|
# ansible-navigator run playbooks/deploy_openshift.yml --tags sno_deploy_install
|
|
# ansible-navigator run playbooks/deploy_openshift.yml --tags opnsense,dns
|
|
# ansible-navigator run playbooks/deploy_openshift.yml --tags keycloak,sno_deploy_oidc
|
|
# ansible-navigator run playbooks/deploy_openshift.yml --tags sno_deploy_certmanager
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Play 1: Create SNO VM in Proxmox
|
|
# ---------------------------------------------------------------------------
|
|
- name: Create SNO VM in Proxmox
|
|
hosts: sno.openshift.toal.ca
|
|
gather_facts: false
|
|
connection: local
|
|
tags: sno_deploy_vm
|
|
|
|
tasks:
|
|
- name: Create VM
|
|
ansible.builtin.include_role:
|
|
name: sno_deploy
|
|
tasks_from: create_vm.yml
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Play 2: Configure OPNsense - Local DNS Overrides
|
|
# Must run BEFORE booting the VM so that api.openshift.toal.ca resolves
|
|
# from within the SNO node during bootstrap.
|
|
# ---------------------------------------------------------------------------
|
|
- name: Configure OPNsense DNS overrides for OpenShift
|
|
hosts: gate.toal.ca
|
|
gather_facts: false
|
|
connection: local
|
|
|
|
module_defaults:
|
|
group/oxlorg.opnsense.all:
|
|
firewall: "{{ opnsense_host }}"
|
|
api_key: "{{ opnsense_api_key }}"
|
|
api_secret: "{{ opnsense_api_secret }}"
|
|
ssl_verify: "{{ opnsense_ssl_verify | default(false) }}"
|
|
api_port: "{{ opnsense_api_port | default(omit) }}"
|
|
|
|
vars:
|
|
__deploy_ocp_cluster_name: "{{ hostvars['sno.openshift.toal.ca']['ocp_cluster_name'] }}"
|
|
__deploy_ocp_base_domain: "{{ hostvars['sno.openshift.toal.ca']['ocp_base_domain'] }}"
|
|
__deploy_sno_ip: "{{ hostvars['sno.openshift.toal.ca']['sno_ip'] }}"
|
|
|
|
tags: opnsense
|
|
|
|
roles:
|
|
- role: opnsense_dns_override
|
|
opnsense_dns_override_entries:
|
|
- hostname: "api.{{ __deploy_ocp_cluster_name }}"
|
|
domain: "{{ __deploy_ocp_base_domain }}"
|
|
value: "{{ __deploy_sno_ip }}"
|
|
type: host
|
|
- hostname: "api-int.{{ __deploy_ocp_cluster_name }}"
|
|
domain: "{{ __deploy_ocp_base_domain }}"
|
|
value: "{{ __deploy_sno_ip }}"
|
|
type: host
|
|
- domain: "apps.{{ __deploy_ocp_cluster_name }}.{{ __deploy_ocp_base_domain }}"
|
|
value: "{{ __deploy_sno_ip }}"
|
|
type: forward
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Play 3: Configure Public DNS Records in DNS Made Easy
|
|
# ---------------------------------------------------------------------------
|
|
- name: Configure public DNS records for OpenShift
|
|
hosts: sno.openshift.toal.ca
|
|
gather_facts: false
|
|
connection: local
|
|
|
|
vars:
|
|
__deploy_public_ip: "{{ hostvars['gate.toal.ca']['haproxy_public_ip'] }}"
|
|
|
|
tags: dns
|
|
|
|
roles:
|
|
- role: dnsmadeeasy_record
|
|
dnsmadeeasy_record_account_key: "{{ dme_account_key }}"
|
|
dnsmadeeasy_record_account_secret: "{{ dme_account_secret }}"
|
|
dnsmadeeasy_record_entries:
|
|
- domain: "{{ ocp_base_domain }}"
|
|
record_name: "api.{{ ocp_cluster_name }}"
|
|
record_type: A
|
|
record_value: "{{ __deploy_public_ip }}"
|
|
record_ttl: "{{ ocp_dns_ttl }}"
|
|
- domain: "{{ ocp_base_domain }}"
|
|
record_name: "*.apps.{{ ocp_cluster_name }}"
|
|
record_type: A
|
|
record_value: "{{ __deploy_public_ip }}"
|
|
record_ttl: "{{ ocp_dns_ttl }}"
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Play 4: Generate Agent ISO and Deploy SNO
|
|
# ---------------------------------------------------------------------------
|
|
- name: Generate Agent ISO and Deploy SNO
|
|
hosts: sno.openshift.toal.ca
|
|
gather_facts: false
|
|
connection: local
|
|
tags: sno_deploy_install
|
|
|
|
tasks:
|
|
- name: Install SNO
|
|
ansible.builtin.include_role:
|
|
name: sno_deploy
|
|
tasks_from: install.yml
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Play 5: Configure Keycloak OIDC client for OpenShift
|
|
# ---------------------------------------------------------------------------
|
|
- name: Configure Keycloak OIDC client for OpenShift
|
|
hosts: openshift
|
|
gather_facts: false
|
|
connection: local
|
|
|
|
tags: keycloak
|
|
|
|
vars:
|
|
keycloak_context: ""
|
|
oidc_client_id: openshift
|
|
oidc_redirect_uri: "https://oauth-openshift.apps.{{ ocp_cluster_name }}.{{ ocp_base_domain }}/oauth2callback/{{ oidc_provider_name }}"
|
|
__oidc_keycloak_api_url: "{{ keycloak_url }}{{ keycloak_context }}"
|
|
|
|
module_defaults:
|
|
middleware_automation.keycloak.keycloak_realm:
|
|
auth_client_id: admin-cli
|
|
auth_keycloak_url: "{{ __oidc_keycloak_api_url }}"
|
|
auth_realm: master
|
|
auth_username: "{{ keycloak_admin_user }}"
|
|
auth_password: "{{ vault_keycloak_admin_password }}"
|
|
validate_certs: "{{ keycloak_validate_certs | default(true) }}"
|
|
middleware_automation.keycloak.keycloak_client:
|
|
auth_client_id: admin-cli
|
|
auth_keycloak_url: "{{ __oidc_keycloak_api_url }}"
|
|
auth_realm: master
|
|
auth_username: "{{ keycloak_admin_user }}"
|
|
auth_password: "{{ vault_keycloak_admin_password }}"
|
|
validate_certs: "{{ keycloak_validate_certs | default(true) }}"
|
|
|
|
tasks:
|
|
|
|
- name: Set OIDC client secret (use vault value or generate random)
|
|
ansible.builtin.set_fact:
|
|
__oidc_client_secret: "{{ vault_oidc_client_secret | default(lookup('community.general.random_string', length=32, special=false)) }}"
|
|
__oidc_secret_generated: "{{ vault_oidc_client_secret is not defined }}"
|
|
no_log: true
|
|
|
|
- name: Ensure Keycloak realm exists
|
|
middleware_automation.keycloak.keycloak_realm:
|
|
realm: "{{ keycloak_realm }}"
|
|
id: "{{ keycloak_realm }}"
|
|
display_name: "{{ keycloak_realm_display_name | default(keycloak_realm | title) }}"
|
|
enabled: true
|
|
state: present
|
|
no_log: "{{ keycloak_no_log | default(true) }}"
|
|
|
|
- name: Create OpenShift OIDC client in Keycloak
|
|
middleware_automation.keycloak.keycloak_client:
|
|
realm: "{{ keycloak_realm }}"
|
|
client_id: "{{ oidc_client_id }}"
|
|
name: "OpenShift - {{ ocp_cluster_name }}"
|
|
description: "OIDC client for OpenShift cluster {{ ocp_cluster_name }}.{{ ocp_base_domain }}"
|
|
enabled: true
|
|
protocol: openid-connect
|
|
public_client: false
|
|
standard_flow_enabled: true
|
|
implicit_flow_enabled: false
|
|
direct_access_grants_enabled: false
|
|
service_accounts_enabled: false
|
|
secret: "{{ __oidc_client_secret }}"
|
|
redirect_uris:
|
|
- "{{ oidc_redirect_uri }}"
|
|
web_origins:
|
|
- "+"
|
|
protocol_mappers:
|
|
- name: groups
|
|
protocol: openid-connect
|
|
protocolMapper: oidc-group-membership-mapper
|
|
config:
|
|
full.path: "false"
|
|
id.token.claim: "true"
|
|
access.token.claim: "true"
|
|
userinfo.token.claim: "true"
|
|
claim.name: groups
|
|
state: present
|
|
no_log: "{{ keycloak_no_log | default(true) }}"
|
|
|
|
- name: Display generated client secret (save this to vault!)
|
|
ansible.builtin.debug:
|
|
msg:
|
|
- "*** GENERATED OIDC CLIENT SECRET — SAVE THIS TO VAULT ***"
|
|
- "vault_oidc_client_secret: {{ __oidc_client_secret }}"
|
|
- ""
|
|
- "Set this in host_vars or pass as --extra-vars on future runs."
|
|
when: __oidc_secret_generated | bool
|
|
|
|
- name: Display Keycloak configuration summary
|
|
ansible.builtin.debug:
|
|
msg:
|
|
- "Keycloak OIDC client configured:"
|
|
- " Realm : {{ keycloak_realm }}"
|
|
- " Client : {{ oidc_client_id }}"
|
|
- " Issuer : {{ keycloak_url }}{{ keycloak_context }}/realms/{{ keycloak_realm }}"
|
|
- " Redirect: {{ oidc_redirect_uri }}"
|
|
verbosity: 1
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Play 6: Post-install OpenShift configuration
|
|
# Configure OIDC OAuth, cert-manager, and delete kubeadmin
|
|
# ---------------------------------------------------------------------------
|
|
- name: Configure OpenShift post-install
|
|
hosts: sno.openshift.toal.ca
|
|
gather_facts: false
|
|
connection: local
|
|
|
|
environment:
|
|
KUBECONFIG: "{{ sno_install_dir }}/auth/kubeconfig"
|
|
K8S_AUTH_VERIFY_SSL: "false"
|
|
|
|
tags:
|
|
- sno_deploy_oidc
|
|
- sno_deploy_certmanager
|
|
- sno_deploy_delete_kubeadmin
|
|
|
|
tasks:
|
|
- name: Configure OpenShift OAuth with OIDC
|
|
ansible.builtin.include_role:
|
|
name: sno_deploy
|
|
tasks_from: configure_oidc.yml
|
|
tags: sno_deploy_oidc
|
|
|
|
- name: Configure cert-manager and LetsEncrypt certificates
|
|
ansible.builtin.include_role:
|
|
name: sno_deploy
|
|
tasks_from: configure_certmanager.yml
|
|
tags: sno_deploy_certmanager
|
|
|
|
- name: Delete kubeadmin user
|
|
ansible.builtin.include_role:
|
|
name: sno_deploy
|
|
tasks_from: delete_kubeadmin.yml
|
|
tags:
|
|
- never
|
|
- sno_deploy_delete_kubeadmin
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Play 7: Install Ansible Automation Platform (opt-in via --tags aap)
|
|
# ---------------------------------------------------------------------------
|
|
- name: Install Ansible Automation Platform
|
|
hosts: sno.openshift.toal.ca
|
|
gather_facts: false
|
|
connection: local
|
|
|
|
environment:
|
|
KUBECONFIG: "{{ sno_install_dir }}/auth/kubeconfig"
|
|
K8S_AUTH_VERIFY_SSL: "false"
|
|
|
|
tags:
|
|
- never
|
|
- aap
|
|
|
|
roles:
|
|
- role: aap_operator
|