Skip to content

Commit

Permalink
Add possibility to run rosa-cross-dc deployment from KC repository an…
Browse files Browse the repository at this point in the history
…d branch (#693)

Closes #522
Signed-off-by: Michal Hajas <[email protected]>
  • Loading branch information
mhajas authored Jan 23, 2024
1 parent 2bdcbf4 commit 15105a9
Show file tree
Hide file tree
Showing 12 changed files with 472 additions and 112 deletions.
16 changes: 15 additions & 1 deletion .github/workflows/rosa-multi-az-cluster-create.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Multi-AZ Clusters - Create and Test
name: Multi-AZ Clusters - Create and Deploy Keycloak

on:
workflow_dispatch:
Expand All @@ -13,6 +13,12 @@ on:
description: 'Check to Create Cluster.'
type: boolean
default: true
keycloakRepository:
description: 'The repository to deploy Keycloak from. If not set nightly image is used'
type: string
keycloakBranch:
description: 'The branch to deploy Keycloak from. If not set nightly image is used'
type: string
workflow_call:
inputs:
clusterPrefix:
Expand All @@ -25,6 +31,12 @@ on:
description: 'Check to Create Cluster'
type: boolean
default: true
keycloakRepository:
description: 'The repository to deploy Keycloak from. If not set nightly image is used'
type: string
keycloakBranch:
description: 'The branch to deploy Keycloak from. If not set nightly image is used'
type: string

env:
CLUSTER_PREFIX: ${{ inputs.clusterPrefix || format('gh-{0}', github.repository_owner) }}
Expand Down Expand Up @@ -124,3 +136,5 @@ jobs:
KC_DB_POOL_MIN_SIZE: 30
KC_DATABASE: "aurora-postgres"
MULTI_AZ: "true"
KC_REPOSITORY: ${{ inputs.keycloakRepository }}
KC_BRANCH: ${{ inputs.keycloakBranch }}
22 changes: 20 additions & 2 deletions doc/kubernetes/modules/ROOT/pages/openshift/cross-site-rosa.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,25 @@ For Keycloak deployment, check xref:customizing-deployment.adoc[Keycloak Customi
Note that not all variable are respected.
As an example, `KC_ISPN_NAMESPACE` is not possible to change since it is automatically computed by this installation script.

=== Warnings / Known issues
=== Customize Keycloak source

Using `--force` will break the keycloak deployment because it patches the keycloak operator deployment with an incorrect image.
This setup, by default, deploys Keycloak from nightly build.
To create a deployment for specific Keycloak source code, git repository and branch can be specified.
This replaces deployments for both Keycloak and Keycloak operator.
Specify the following variables for using custom source code:


|===
|Variable |Details

|KC_REPOSITORY
|Git repository to clone Keycloak source code from.
Example: https://github.com/keycloak/keycloak.git

Note: SSH repositories may not work in Github Actions as SSH keys may not be configured.

|KC_BRANCH
|The branch within `KC_REPOSITORY` to use.

|===

61 changes: 61 additions & 0 deletions provision/keycloak-tasks/Taskfile.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# This Taskfile is used only for testing purposes of tasks defined in Utils.yaml
version: '3'
includes:
utils:
taskfile: ./Utils.yaml
internal: true
output: prefixed

dotenv: [ '.env' ]

required:
- KUBECONFIG
- NAMESPACE

vars:
KC_REPOSITORY: '{{.KC_REPOSITORY | default ""}}'
KC_BRANCH: '{{.KC_BRANCH | default ""}}'

# To compute Infinispan namespace
KC_NAMESPACE_PREFIX: '{{default "$(whoami)-" .KC_NAMESPACE_PREFIX}}'
KC_ISPN_NAMESPACE: '{{.KC_NAMESPACE_PREFIX}}keycloak'
ISPN_DIR: "{{.ROOT_DIR}}/../infinispan"
ROUTE53_DIR: "{{.ROOT_DIR}}/../aws/route53"
RDS_DIR: "{{.ROOT_DIR}}/../aws/rds"
KC_DIR: "{{.ROOT_DIR}}/../openshift"
ANSIBLE_DIR: "{{.ROOT_DIR}}/../../ansible"
PYTHON_DIR: "{{.ROOT_DIR}}/../../benchmark/src/main/python"
BENCHMARK_DIR: "{{.ROOT_DIR}}/../../benchmark/src/main/content/bin"
KC_ADMIN_PASSWORD:
sh: aws secretsmanager get-secret-value --region eu-central-1 --secret-id keycloak-master-password --query SecretString --output text --no-cli-pager

KB_RETENTION: '{{default "168h" .KB_RETENTION}}'
KC_OTEL: '{{default "false" .KC_OTEL}}'
KC_CRYOSTAT: '{{default "true" .KC_CRYOSTAT}}'
KC_OTEL_SAMPLING_PERCENTAGE: '{{default "0.001" .KC_OTEL_SAMPLING_PERCENTAGE}}'
KC_DB_POOL_INITIAL_SIZE: '{{default "5" .KC_DB_POOL_INITIAL_SIZE}}'
KC_DB_POOL_MAX_SIZE: '{{default "10" .KC_DB_POOL_MAX_SIZE}}'
KC_DB_POOL_MIN_SIZE: '{{default "5" .KC_DB_POOL_MIN_SIZE}}'
KC_DATABASE: '{{default "postgres" .KC_DATABASE}}'
KC_OPERATOR_TAG: '{{default "nightly" .KC_OPERATOR_TAG}}'
KC_CONTAINER_IMAGE: '{{default "" .KC_CONTAINER_IMAGE}}'
KC_INSTANCES: '{{default "1" .KC_INSTANCES}}'
KC_CPU_REQUESTS: '{{default "0" .KC_CPU_REQUESTS}}'
KC_CPU_LIMITS: '{{default "" .KC_CPU_LIMITS}}'
KC_MEMORY_REQUESTS_MB: '{{default "1024" .KC_MEMORY_REQUESTS_MB}}'
KC_MEMORY_LIMITS_MB: '{{default "1024" .KC_MEMORY_LIMITS_MB}}'
KC_HEAP_INIT_MB: '{{default "64" .KC_HEAP_INIT_MB}}'
KC_HEAP_MAX_MB: '{{default "512" .KC_HEAP_MAX_MB}}'
KC_METASPACE_INIT_MB: '{{default "96" .KC_METASPACE_INIT_MB}}'
KC_METASPACE_MAX_MB: '{{default "256" .KC_METASPACE_MAX_MB}}'
KC_CUSTOM_INFINISPAN_CONFIG: '{{default "true" .KC_CUSTOM_INFINISPAN_CONFIG}}'
KC_CUSTOM_INFINISPAN_CONFIG_FILE: '{{default "config/kcb-infinispan-cache-config.xml" .KC_CUSTOM_INFINISPAN_CONFIG_FILE}}'
KC_REMOTE_STORE: '{{default "false" .KC_REMOTE_STORE}}'
KC_REMOTE_STORE_HOST: '{{default "localhost" .KC_REMOTE_STORE_HOST}}'
KC_REMOTE_STORE_PORT: '{{default "11222" .KC_REMOTE_STORE_PORT}}'
KC_DISABLE_STICKY_SESSION: '{{default "false" .KC_DISABLE_STICKY_SESSION}}'

tasks:
default:
cmds:
- task: utils:install-keycloak
227 changes: 227 additions & 0 deletions provision/keycloak-tasks/Utils.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,227 @@
# https://taskfile.dev
version: '3'

tasks:

no-op:
desc: "No-op task"
internal: true

clone-keycloak:
desc: "Clone the Keycloak repository"
internal: true
dir: ".task"
requires:
vars:
- KC_REPOSITORY
- KC_BRANCH
cmds:
- rm -rf "keycloak" || true
- git clone --branch "{{.KC_BRANCH}}" "{{.KC_REPOSITORY}}" "keycloak"
- git -C "keycloak" checkout "{{.KC_BRANCH}}"
- git -C "keycloak" pull
generates:
- ./keycloak/**/*.*
status:
- test -d keycloak
- test -n "$(ls -A keycloak)"
- test "{{.KC_REPOSITORY}}" == "$(git -C keycloak remote get-url origin)"
- test "{{.KC_BRANCH}}" == "$(git -C keycloak rev-parse --abbrev-ref HEAD)"

build-keycloak-dist:
desc: "Build the Keycloak distribution and operator"
label: "{{.TASK}}-{{.CURRENT_HASH}}"
internal: true
dir: ".task/keycloak"
vars:
CURRENT_HASH:
sh: git rev-parse HEAD
cmd: ./mvnw clean install -DskipTests -Poperator -am -pl quarkus/dist,operator
sources:
- pom.xml # We are relying on git hash to detect changes (see `label:` above) but we need something as a source for it to work
generates:
- quarkus/dist/target/keycloak-*.tar.gz
- operator/target/keycloak-*.jar

prepare-keycloak-images-openshift:
desc: "Create images for the current build of Keycloak distribution"
label: "{{.TASK}}-{{.ROSA_CLUSTER_NAME}}"
internal: true
requires:
task:
- build-keycloak-dist
vars:
- NAMESPACE
- KUBECONFIG
- ROSA_CLUSTER_NAME
vars:
ARCHIVE_NAME:
sh: ls .task/keycloak/quarkus/dist/target/keycloak-*.tar.gz | xargs -n 1 basename
cmds:
- KUBECONFIG="{{.KUBECONFIG}}" oc create namespace "{{.NAMESPACE}}" || true
- KUBECONFIG={{.KUBECONFIG}} helm uninstall --namespace {{.NAMESPACE}} keycloak-build-config || true
# Create custom Keycloak resources for both Keycloak and Keycloak operator
- >
KUBECONFIG="{{.KUBECONFIG}}" helm upgrade --install keycloak-build-config --namespace "{{.NAMESPACE}}"
--set "namespace={{.NAMESPACE}}"
--set "archiveName={{.ARCHIVE_NAME}}"
./keycloak-image-helm
# Start Keycloak image build
- cp "$(ls .task/keycloak/quarkus/dist/target/keycloak-*.tar.gz)" ".task/keycloak/quarkus/container/"
- KUBECONFIG="{{.KUBECONFIG}}" oc start-build -n {{.NAMESPACE}} keycloak --from-dir ".task/keycloak/quarkus/container" --follow
- echo "image-registry.openshift-image-registry.svc:5000/{{.NAMESPACE}}/keycloak:latest" > .task/var-CUSTOM_CONTAINER_IMAGE_FILE

# Start Keycloak operator image build
- KUBECONFIG="{{.KUBECONFIG}}" oc start-build -n {{.NAMESPACE}} keycloak-operator --from-dir ".task/keycloak/operator" --follow
- echo "image-registry.openshift-image-registry.svc:5000/{{.NAMESPACE}}/keycloak-operator:latest" > .task/var-KC_OPERATOR_CONTAINER_IMAGE
sources:
- quarkus/dist/target/keycloak-*.tar.gz
- operator/target/keycloak-*.jar
status:
- test -n "$(KUBECONFIG="{{.KUBECONFIG}}" helm list --namespace {{.NAMESPACE}} --filter keycloak-build-config -q)"
preconditions:
- test -f {{.KUBECONFIG}}

install-keycloak-operator:
desc: "Install the Keycloak operator"
internal: true
requires:
vars:
- NAMESPACE
- KUBECONFIG
vars:
OPERATOR_IMAGE:
sh: cat .task/var-KC_OPERATOR_CONTAINER_IMAGE || echo ""
EXTERNAL_OPERATOR_PREFIX: "https://raw.githubusercontent.com/keycloak/keycloak-k8s-resources/refs/tags/{{.KC_OPERATOR_TAG}}/kubernetes/"
CUSTOM_OPERATOR_PREFIX: ".task/keycloak/operator/target/kubernetes/"
CURRENT_PREFIX: '{{ ternary .CUSTOM_OPERATOR_PREFIX .EXTERNAL_OPERATOR_PREFIX (hasPrefix "image-registry.openshift-image-registry.svc:5000" .OPERATOR_IMAGE) }}'
cmds:
- KUBECONFIG="{{.KUBECONFIG}}" kubectl create namespace "{{.NAMESPACE}}" || true
- KUBECONFIG="{{.KUBECONFIG}}" kubectl -n {{.NAMESPACE}} apply -f {{.CURRENT_PREFIX}}keycloaks.k8s.keycloak.org-v1.yml
- KUBECONFIG="{{.KUBECONFIG}}" kubectl -n {{.NAMESPACE}} apply -f {{.CURRENT_PREFIX}}keycloakrealmimports.k8s.keycloak.org-v1.yml
- KUBECONFIG="{{.KUBECONFIG}}" kubectl -n {{.NAMESPACE}} delete deployment/keycloak-operator || true
- KUBECONFIG="{{.KUBECONFIG}}" kubectl -n {{.NAMESPACE}} apply -f {{.CURRENT_PREFIX}}kubernetes.yml
- task: patch-keycloak-operator-image
vars:
NAMESPACE: "{{.NAMESPACE}}"
KUBECONFIG: "{{.KUBECONFIG}}"
preconditions:
- test -f {{.KUBECONFIG}}

patch-keycloak-operator-image:
desc: "Patch the Keycloak operator image"
internal: true
requires:
vars:
- NAMESPACE
- KUBECONFIG
vars:
OPERATOR_IMAGE:
sh: cat .task/var-KC_OPERATOR_CONTAINER_IMAGE 2> /dev/null || echo ""
cmds:
- |
(test -n "{{.OPERATOR_IMAGE}}" && KUBECONFIG="{{.KUBECONFIG}}" kubectl patch deployment keycloak-operator -n {{.NAMESPACE}} --type json -p '[{"op": "replace", "path": "/spec/template/spec/containers/0/image", "value": "{{.OPERATOR_IMAGE}}"}]') || true
preconditions:
- test -f {{.KUBECONFIG}}

prepare-custom-images:
des: "Prepare custom images for Keycloak and Keycloak operator"
internal: true
requires:
vars:
- KC_REPOSITORY
- KC_BRANCH
- NAMESPACE
- KUBECONFIG
- ROSA_CLUSTER_NAME
cmds:
- task: clone-keycloak
- task: build-keycloak-dist
- task: prepare-keycloak-images-openshift
vars:
NAMESPACE: "{{.NAMESPACE}}"
KUBECONFIG: "{{.KUBECONFIG}}"
ROSA_CLUSTER_NAME: "{{.ROSA_CLUSTER_NAME}}"

install-keycloak:
des: "Install Keycloak to the given namespace and cluster"
internal: true
requires:
vars:
- KUBECONFIG
- NAMESPACE
- KC_HOSTNAME_SUFFIX
- KC_ADMIN_PASSWORD
- ROSA_CLUSTER_NAME
vars:
CURRENT_KC_CONTAINER_IMAGE: '{{ ternary "$(cat .task/var-CUSTOM_CONTAINER_IMAGE_FILE 2> /dev/null || echo \"\")" .KC_CONTAINER_IMAGE (empty .KC_CONTAINER_IMAGE) }}'
cmds:
- task: '{{if .KC_REPOSITORY}}prepare-custom-images{{else}}no-op{{end}}'
vars:
KUBECONFIG: "{{.KUBECONFIG}}"
NAMESPACE: "{{.NAMESPACE}}"
ROSA_CLUSTER_NAME: "{{.ROSA_CLUSTER_NAME}}"
- task: install-keycloak-operator
vars:
NAMESPACE: "{{.NAMESPACE}}"
KUBECONFIG: "{{.KUBECONFIG}}"
- >
KUBECONFIG="{{.KUBECONFIG}}"
helm upgrade --install keycloak --namespace {{.NAMESPACE}}
--set hostname={{.KC_HOSTNAME_SUFFIX}}
--set keycloakHostname={{.KC_HOSTNAME_OVERRIDE}}
--set keycloakHealthHostname={{.KC_HEALTH_HOSTNAME}}
--set otel={{.KC_OTEL}}
--set otelSamplingPercentage={{.KC_OTEL_SAMPLING_PERCENTAGE}}
--set dbPoolInitialSize={{.KC_DB_POOL_INITIAL_SIZE}}
--set dbPoolMinSize={{.KC_DB_POOL_MIN_SIZE}}
--set dbPoolMaxSize={{.KC_DB_POOL_MAX_SIZE}}
--set dbUrl={{ .KC_DATABASE_URL }}
--set database={{.KC_DATABASE}}
--set keycloakImage={{.CURRENT_KC_CONTAINER_IMAGE}}
--set instances={{ .KC_INSTANCES }}
--set cpuRequests={{ .KC_CPU_REQUESTS }}
--set cpuLimits={{ .KC_CPU_LIMITS }}
--set memoryRequestsMB={{ .KC_MEMORY_REQUESTS_MB }}
--set memoryLimitsMB={{ .KC_MEMORY_LIMITS_MB }}
--set heapInitMB={{ .KC_HEAP_INIT_MB }}
--set heapMaxMB={{ .KC_HEAP_MAX_MB }}
--set metaspaceInitMB={{ .KC_METASPACE_INIT_MB }}
--set metaspaceMaxMB={{ .KC_METASPACE_MAX_MB }}
--set infinispan.jgroupsTls={{ .KC_JGROUPS_TLS }}
--set infinispan.customConfig={{ .KC_CUSTOM_INFINISPAN_CONFIG }}
--set infinispan.configFile={{ .KC_CUSTOM_INFINISPAN_CONFIG_FILE }}
--set infinispan.remoteStore.enabled=true
--set infinispan.remoteStore.host=infinispan.{{.KC_ISPN_NAMESPACE}}.svc
--set infinispan.remoteStore.port=11222
--set infinispan.remoteStore.username=developer
--set infinispan.remoteStore.password={{ .RS_HOT_ROD_PASSWORD | default .KEYCLOAK_MASTER_PASSWORD }}
--set infinispan.site={{ .ROSA_CLUSTER_NAME }}
--set cryostat={{ .KC_CRYOSTAT }}
--set sqlpad=false
--set environment=openshift
--set namespace={{.NAMESPACE}}
--set keycloakAdminPassword="{{.KC_ADMIN_PASSWORD}}"
--set disableIngressStickySession={{ .KC_DISABLE_STICKY_SESSION }}
--set nodePortsEnabled=false
../minikube/keycloak
preconditions:
- test -f {{.KUBECONFIG}}

uninstall-keycloak:
internal: true
requires:
vars:
- KUBECONFIG
- NAMESPACE
cmds:
- KUBECONFIG={{.KUBECONFIG}} helm uninstall --namespace {{.NAMESPACE}} keycloak || true
- KUBECONFIG={{.KUBECONFIG}} helm uninstall --namespace {{.NAMESPACE}} keycloak-build-config || true
status:
- test -z "$(KUBECONFIG={{.KUBECONFIG}} helm list --namespace {{.NAMESPACE}} --filter keycloak -q)"
preconditions:
- test -f {{.KUBECONFIG}}



24 changes: 24 additions & 0 deletions provision/keycloak-tasks/keycloak-image-helm/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
apiVersion: v2
name: keycloak-image-helm
description: Keycloak image build config

# A chart can be either an 'application' or a 'library' chart.
#
# Application charts are a collection of templates that can be packaged into versioned archives
# to be deployed.
#
# Library charts provide useful utilities or functions for the chart developer. They're included as
# a dependency of application charts to inject those utilities and functions into the rendering
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
type: application

# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 0.1.0

# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using.
# It is recommended to use it with quotes.
appVersion: "14.0"
Loading

0 comments on commit 15105a9

Please sign in to comment.