Files
toallab-automation/playbooks/deploy_aap.yml

220 lines
9.3 KiB
YAML

---
# Deploy Ansible Automation Platform on OpenShift
#
# Authenticates via the aap-deployer ServiceAccount token (not kubeadmin).
# The token is stored in 1Password and loaded via vault_aap_deployer_token.
#
# Prerequisites:
# - OpenShift cluster deployed (deploy_openshift.yml)
# - aap-deployer ServiceAccount provisioned:
# ansible-navigator run playbooks/deploy_openshift.yml --tags sno_deploy_service_accounts
# - SA token saved to 1Password as vault_aap_deployer_token
#
# Keycloak OIDC prerequisites (--tags aap_configure_keycloak,aap_configure_oidc):
# - Keycloak realm exists (configured via deploy_openshift.yml)
# - vault_aap_oidc_client_secret in 1Password (or it will be generated and displayed)
# - In host_vars for the aap host:
# aap_gateway_url: "https://aap.apps.<cluster>.<domain>"
# aap_oidc_client_id: aap
# aap_oidc_issuer: "https://keycloak.example.com/realms/<realm>"
# aap_oidc_public_key: "<RS256 public key from Keycloak realm Keys tab>"
#
# Play order:
# Play 0: aap_configure_keycloak — Create Keycloak OIDC client for AAP Gateway
# Play 1: (default) — Install AAP via aap_operator role
# Play 2: aap_configure_oidc — Configure OIDC Authentication Method in AAP Gateway
#
# Usage:
# ansible-navigator run playbooks/deploy_aap.yml
# ansible-navigator run playbooks/deploy_aap.yml --tags aap_configure_keycloak
# ansible-navigator run playbooks/deploy_aap.yml --tags aap_configure_oidc
# ansible-navigator run playbooks/deploy_aap.yml --tags aap_configure_keycloak,aap_configure_oidc
# ---------------------------------------------------------------------------
# Play 0: Create Keycloak OIDC client for AAP (optional)
# Runs on openshift hosts to access keycloak_url/keycloak_realm host vars.
# Creates the OIDC client in Keycloak with the correct AAP Gateway callback URI.
# ---------------------------------------------------------------------------
- name: Configure Keycloak OIDC client for AAP
hosts: openshift
gather_facts: false
connection: local
tags:
- never
- aap_configure_keycloak
vars:
__aap_keycloak_api_url: "{{ keycloak_url }}{{ keycloak_context | default('') }}"
__aap_oidc_client_id: "{{ aap_oidc_client_id | default('aap') }}"
# AAP operator generates the Gateway route as {platform_name}-{namespace}.apps.{cluster}.{domain}
# e.g. platform 'aap' in namespace 'aap' → aap-aap.apps.openshift.toal.ca
__aap_platform_name: "{{ aap_operator_platform_name | default('aap') }}"
__aap_namespace: "{{ aap_operator_namespace | default('aap') }}"
__aap_oidc_redirect_uris:
- "https://{{ __aap_platform_name }}-{{ __aap_namespace }}.apps.{{ ocp_cluster_name }}.{{ ocp_base_domain }}/accounts/profile/callback/"
module_defaults:
middleware_automation.keycloak.keycloak_client:
auth_client_id: admin-cli
auth_keycloak_url: "{{ __aap_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 AAP OIDC client secret (vault value or generated)
ansible.builtin.set_fact:
__aap_oidc_client_secret: "{{ vault_aap_oidc_client_secret | default(lookup('community.general.random_string', length=32, special=false)) }}"
__aap_oidc_secret_generated: "{{ vault_aap_oidc_client_secret is not defined }}"
no_log: true
- name: Create AAP OIDC client in Keycloak
middleware_automation.keycloak.keycloak_client:
realm: "{{ keycloak_realm }}"
client_id: "{{ __aap_oidc_client_id }}"
name: "Ansible Automation Platform"
description: "OIDC client for AAP Gateway on {{ 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: "{{ __aap_oidc_client_secret }}"
redirect_uris: "{{ __aap_oidc_redirect_uris }}"
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 AAP OIDC CLIENT SECRET — SAVE THIS TO VAULT ***"
- "vault_aap_oidc_client_secret: {{ __aap_oidc_client_secret }}"
- ""
- "Save to 1Password and reference as vault_aap_oidc_client_secret."
when: __aap_oidc_secret_generated | bool
- name: Display Keycloak AAP OIDC configuration summary
ansible.builtin.debug:
msg:
- "Keycloak AAP OIDC client configured:"
- " Realm : {{ keycloak_realm }}"
- " Client : {{ __aap_oidc_client_id }}"
- " Issuer : {{ __aap_keycloak_api_url }}/realms/{{ keycloak_realm }}"
- " Redirect : {{ __aap_oidc_redirect_uris | join(', ') }}"
- ""
- "Set in host_vars for the aap host:"
- " aap_gateway_url: https://{{ __aap_platform_name }}-{{ __aap_namespace }}.apps.{{ ocp_cluster_name }}.{{ ocp_base_domain }}"
- " aap_oidc_issuer: {{ __aap_keycloak_api_url }}/realms/{{ keycloak_realm }}"
- ""
- "Then run: --tags aap_configure_oidc to register the authenticator in AAP."
verbosity: 1
# ---------------------------------------------------------------------------
# Play 1: Install Ansible Automation Platform
# ---------------------------------------------------------------------------
- name: Install Ansible Automation Platform
hosts: aap
gather_facts: false
connection: local
pre_tasks:
- name: Verify aap-deployer token is available
ansible.builtin.assert:
that:
- vault_aap_deployer_token is defined
- vault_aap_deployer_token | length > 0
fail_msg: >-
vault_aap_deployer_token is not set. Provision the ServiceAccount with:
ansible-navigator run playbooks/deploy_openshift.yml --tags sno_deploy_service_accounts
Then save the displayed token to 1Password as vault_aap_deployer_token.
# environment:
# K8S_AUTH_HOST: "{{ aap_k8s_api_url }}"
# K8S_AUTH_API_KEY: "{{ vault_aap_deployer_token }}"
roles:
- role: aap_operator
# ---------------------------------------------------------------------------
# Play 2: Configure Keycloak OIDC Authentication Method in AAP Gateway (optional)
# Uses infra.aap_configuration.gateway_authenticators to register the OIDC
# provider via the AAP Gateway API. Run after Play 1 (AAP must be Running).
#
# Requires in host_vars for the aap host:
# aap_gateway_url: "https://aap.apps.<cluster>.<domain>"
# aap_oidc_issuer: "https://keycloak.example.com/realms/<realm>"
# aap_oidc_client_id: aap (optional, default: aap)
# aap_oidc_public_key: "<RS256 public key from Keycloak realm Keys tab>"
# Vault:
# vault_aap_oidc_client_secret — OIDC client secret from Keycloak
# ---------------------------------------------------------------------------
- name: Configure Keycloak OIDC Authentication in AAP Gateway
hosts: aap
gather_facts: false
connection: local
tags:
- never
- aap_configure_oidc
vars:
__aap_namespace: "{{ aap_operator_namespace | default('aap') }}"
__aap_platform_name: "{{ aap_operator_platform_name | default('aap') }}"
environment:
K8S_AUTH_HOST: "{{ aap_k8s_api_url }}"
K8S_AUTH_API_KEY: "{{ vault_aap_deployer_token }}"
pre_tasks:
- name: Fetch AAP admin password from K8s secret
kubernetes.core.k8s_info:
api_version: v1
kind: Secret
namespace: "{{ __aap_namespace }}"
name: "{{ __aap_platform_name }}-admin-password"
register: __aap_admin_secret
no_log: false
- name: Set AAP admin password fact
ansible.builtin.set_fact:
__aap_admin_password: "{{ __aap_admin_secret.resources[0].data.password | b64decode }}"
no_log: true
tasks:
- name: Configure Keycloak OIDC authenticator in AAP Gateway
ansible.builtin.include_role:
name: infra.aap_configuration.gateway_authenticators
vars:
aap_hostname: "{{ aap_gateway_url }}"
aap_username: "{{ aap_operator_admin_user | default('admin') }}"
aap_password: "{{ __aap_admin_password }}"
gateway_authenticators:
- name: Keycloak
type: ansible_base.authentication.authenticator_plugins.keycloak
slug: keycloak
enabled: true
configuration:
KEY: "{{ aap_oidc_client_id | default('aap') }}"
SECRET: "{{ vault_aap_oidc_client_secret }}"
PUBLIC_KEY: "{{ aap_oidc_public_key }}"
ACCESS_TOKEN_URL: "{{ aap_oidc_issuer }}/protocol/openid-connect/token"
AUTHORIZATION_URL: "{{ aap_oidc_issuer }}/protocol/openid-connect/auth"
GROUPS_CLAIM: "groups"
state: present