Skip to content

Commit 8341854

Browse files
wtripp180901Matt PryorJohnGarbutt
authored
Allow standalone Kubernetes applications (#848)
* Support configuring OIDC auth for Azimuth * Support for configuring a realm and OIDC client using CRDs * Initial configuration for standalone apps * Remove template generation + additional config options * Only migrate CaaS clusters when they are enabled * Pick up apps operator version with fixed metrics * Add sealed secrets to deployment * Propagate Zenith connection info to apps operator * Pick up version that supports Zenith operator * Add dependency updates for new components * bumped dev charts * updated dependencies * azimuth fix * null provider fix * Update main.yml * Update main.yml * Update main.yml --------- Co-authored-by: Matt Pryor <[email protected]> Co-authored-by: John Garbutt <[email protected]>
1 parent 0a9ba63 commit 8341854

File tree

9 files changed

+405
-51
lines changed

9 files changed

+405
-51
lines changed

.github/workflows/update-dependencies.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,12 @@ jobs:
5151
prereleases: "yes"
5252
version_jsonpath: azimuth_chart_version
5353

54+
- key: azimuth-apps-operator
55+
path: ./roles/azimuth_apps_operator/defaults/main.yml
56+
repository: azimuth-cloud/azimuth-apps-operator
57+
prereleases: "yes"
58+
version_jsonpath: azimuth_apps_operator_chart_version
59+
5460
- key: azimuth-caas-operator
5561
path: ./roles/azimuth_caas_operator/defaults/main.yml
5662
repository: azimuth-cloud/azimuth-caas-operator
@@ -280,6 +286,12 @@ jobs:
280286
chart_name_jsonpath: velero_csi_snapshot_controller_chart_name
281287
chart_version_jsonpath: velero_csi_snapshot_controller_chart_version
282288

289+
- key: sealed-secrets
290+
path: ./roles/sealed_secrets/defaults/main.yml
291+
chart_repo_jsonpath: sealed_secrets_chart_repo
292+
chart_name_jsonpath: sealed_secrets_chart_name
293+
chart_version_jsonpath: sealed_secrets_chart_version
294+
283295
- key: velero
284296
path: ./roles/velero/defaults/main.yml
285297
chart_repo_jsonpath: velero_chart_repo

playbooks/deploy.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
alertmanager_config_slack_webhook_url
1212
- role: azimuth_cloud.azimuth_ops.flux
1313
when: flux_enabled
14+
- role: azimuth_cloud.azimuth_ops.sealed_secrets
1415
- role: azimuth_cloud.azimuth_ops.certmanager
1516
when: certmanager_enabled or azimuth_kubernetes_enabled
1617
- role: azimuth_cloud.azimuth_ops.kubernetes_dashboard
@@ -40,6 +41,8 @@
4041
when: azimuth_apps_enabled
4142
- role: azimuth_cloud.azimuth_ops.azimuth_capi_operator
4243
when: azimuth_kubernetes_enabled
44+
- role: azimuth_cloud.azimuth_ops.azimuth_apps_operator
45+
when: azimuth_apps_enabled
4346
- azimuth_cloud.azimuth_ops.azimuth
4447
# Ensure that Consul is uninstalled
4548
post_tasks:

playbooks/provision_cluster.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969

7070
- include_role:
7171
name: azimuth_cloud.azimuth_ops.community_images
72+
when: community_images_enabled is not defined or community_images_enabled
7273

7374
# For a single node install, we put the monitoring and ingress controller on the K3S cluster
7475
- block:

roles/azimuth/defaults/main.yml

Lines changed: 132 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,62 @@ azimuth_curated_sizes: []
9494
# description: >-
9595
# {% raw %}{{ cpus }} CPUs, {{ ram }} RAM, {{ disk }} disk, {{ ephemeral_disk }} ephemeral disk{% endraw %}
9696

97+
# The authentication type to use - oidc and openstack are supported
98+
azimuth_authentication_type: openstack
99+
100+
# Settings for OIDC authentication
101+
# The name of the identity realm to create for Azimuth users
102+
# This will result in a realm in Keycloak named {namespace}-{name}, e.g. azimuth-users
103+
# Only used if azimuth_oidc_issuer_url is not given
104+
azimuth_oidc_users_realm_name: users
105+
# The OIDC issuer URL (must support the OIDC discovery specification)
106+
# If not given, this is set to the issuer URL for the identity realm
107+
azimuth_oidc_issuer_url:
108+
# The OIDC client ID
109+
# If an identity realm is being used and no client secret is given, a client is created
110+
# with this ID using the spec that follows
111+
azimuth_oidc_client_id: azimuth-portal
112+
# The spec for the OIDC client
113+
# Used to create an OIDC client when no client secret is given
114+
azimuth_oidc_client_spec:
115+
# Use the realm that we created
116+
realmName: "{{ azimuth_oidc_users_realm_name }}"
117+
# Azimuth uses a confidential client with the authcode grant
118+
public: false
119+
grantTypes: [AuthorizationCode]
120+
redirectUris:
121+
- >-
122+
{{
123+
"{}://{}/auth/oidc/complete/".format(
124+
'https' if azimuth_ingress_tls_enabled else 'http',
125+
azimuth_ingress_host
126+
)
127+
}}
128+
# The client secret
129+
# If not given and an identity realm is being used, a client is created - see above
130+
azimuth_oidc_client_secret: "{{ undef(hint = 'azimuth_oidc_client_secret is required') }}"
131+
# The scope to use when requesting tokens
132+
azimuth_oidc_scope: "openid profile email groups"
133+
# The claims to use for the user ID, username, email and groups respectively
134+
azimuth_oidc_userid_claim: sub
135+
azimuth_oidc_username_claim: preferred_username
136+
azimuth_oidc_email_claim: email
137+
azimuth_oidc_groups_claim: groups
138+
# Indicates whether to verify SSL when talking to the OIDC provider
139+
azimuth_oidc_verify_ssl: true
140+
# The aggregated settings object for OIDC authentication
141+
azimuth_oidc_authentication:
142+
issuerUrl: "{{ azimuth_oidc_issuer_url }}"
143+
scope: "{{ azimuth_oidc_scope }}"
144+
claims:
145+
userid: "{{ azimuth_oidc_userid_claim }}"
146+
username: "{{ azimuth_oidc_username_claim }}"
147+
email: "{{ azimuth_oidc_email_claim }}"
148+
groups: "{{ azimuth_oidc_groups_claim }}"
149+
clientID: "{{ azimuth_oidc_client_id }}"
150+
clientSecret: "{{ azimuth_oidc_client_secret }}"
151+
verifySsl: "{{ azimuth_oidc_verify_ssl }}"
152+
97153
# Settings for OpenStack authentication
98154
#  The Keystone auth URL
99155
azimuth_openstack_auth_url: "{{ undef(hint = 'azimuth_openstack_auth_url is required') }}"
@@ -147,62 +203,81 @@ azimuth_authenticator_federated_identity_providers:
147203
provider: "{{ azimuth_authenticator_federated_provider }}"
148204
# A human-readble label for the identity provider, used in the selection form
149205
label: "{{ azimuth_authenticator_federated_label }}"
150-
# The authentication settings, structured as defaults + overrides
151-
azimuth_authentication_defaults:
152-
type: openstack
153-
openstack: >-
154-
{{-
155-
{
156-
"authUrl": azimuth_openstack_auth_url,
157-
"interface": azimuth_openstack_interface,
158-
"verifySsl": azimuth_openstack_verify_ssl,
159-
"appcred": {
160-
"hidden": azimuth_authenticator_appcred_hidden,
161-
},
162-
"password": {
163-
"enabled": azimuth_authenticator_password_enabled,
164-
},
165-
"federated": {
166-
"enabled": azimuth_authenticator_federated_enabled,
167-
},
168-
} |
169-
combine(
170-
{ "region": azimuth_openstack_region }
171-
if azimuth_openstack_region
206+
# The aggregated settings object for OpenStack auth
207+
azimuth_openstack_authentication: >-
208+
{{-
209+
{
210+
"authUrl": azimuth_openstack_auth_url,
211+
"interface": azimuth_openstack_interface,
212+
"verifySsl": azimuth_openstack_verify_ssl,
213+
"appcred": {
214+
"hidden": azimuth_authenticator_appcred_hidden,
215+
},
216+
"password": {
217+
"enabled": azimuth_authenticator_password_enabled,
218+
},
219+
"federated": {
220+
"enabled": azimuth_authenticator_federated_enabled,
221+
},
222+
} |
223+
combine(
224+
{ "region": azimuth_openstack_region }
225+
if azimuth_openstack_region
226+
else {}
227+
) |
228+
combine(
229+
(
230+
{
231+
"password": {
232+
"domains": azimuth_authenticator_password_domains,
233+
},
234+
}
235+
if azimuth_authenticator_password_enabled
172236
else {}
173-
) |
174-
combine(
175-
(
176-
{
177-
"password": {
178-
"domains": azimuth_authenticator_password_domains,
179-
},
180-
}
181-
if azimuth_authenticator_password_enabled
182-
else {}
183-
),
184-
recursive = True
185-
) |
186-
combine(
187-
(
188-
{
189-
"federated": {
190-
"identityProviders": azimuth_authenticator_federated_identity_providers,
191-
},
192-
}
193-
if azimuth_authenticator_federated_enabled
194-
else {}
195-
),
196-
recursive = True
197-
)
198-
}}
237+
),
238+
recursive = True
239+
) |
240+
combine(
241+
(
242+
{
243+
"federated": {
244+
"identityProviders": azimuth_authenticator_federated_identity_providers,
245+
},
246+
}
247+
if azimuth_authenticator_federated_enabled
248+
else {}
249+
),
250+
recursive = True
251+
)
252+
}}
253+
254+
# The authentication settings, structured as defaults + overrides
255+
azimuth_authentication_defaults: >-
256+
{{-
257+
{ "type": azimuth_authentication_type } |
258+
combine(
259+
{ "openstack": azimuth_openstack_authentication }
260+
if azimuth_authentication_type == "openstack"
261+
else {}
262+
) |
263+
combine(
264+
{ "oidc": azimuth_oidc_authentication }
265+
if azimuth_authentication_type == "oidc"
266+
else {}
267+
)
268+
}}
199269
azimuth_authentication_overrides: {}
200270
azimuth_authentication: >-
201271
{{-
202272
azimuth_authentication_defaults |
203273
combine(azimuth_authentication_overrides, recursive = True)
204274
}}
205275
276+
# The type of provider to use
277+
# Setting this to "null" disables all cloud functionality, only retaining support
278+
# for deploying onto a pre-configured Kubernetes cluster for each tenant
279+
azimuth_cloud_provider_type: openstack
280+
206281
# OpenStack provider settings
207282
# The template to use when searching for the internal network
208283
# Only used if the internal network is not tagged
@@ -222,7 +297,6 @@ azimuth_openstack_create_internal_net: true
222297
azimuth_openstack_internal_net_cidr: 192.168.3.0/24
223298
# The nameservers to set on auto-created tenant internal networks
224299
azimuth_openstack_internal_net_dns_nameservers: []
225-
226300
# Azimuth OpenStack provider configuration
227301
azimuth_openstack_provider: >-
228302
{{-
@@ -367,8 +441,15 @@ azimuth_release_defaults:
367441
supportUrl: "{{ azimuth_support_url }}"
368442
curatedSizes: "{{ azimuth_curated_sizes }}"
369443
authentication: "{{ azimuth_authentication }}"
370-
provider:
371-
openstack: "{{ azimuth_openstack_provider }}"
444+
provider: >-
445+
{{-
446+
{ "type": azimuth_cloud_provider_type } |
447+
combine(
448+
{ "openstack": azimuth_openstack_provider }
449+
if azimuth_cloud_provider_type == "openstack"
450+
else {}
451+
)
452+
}}
372453
apps: >-
373454
{{-
374455
{

roles/azimuth/tasks/main.yml

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,112 @@
3434
tls.key: "{{ azimuth_ingress_tls_key }}"
3535
when: azimuth_ingress_tls_certificate
3636

37+
- block:
38+
- name: Ensure identity realm exists for Azimuth users
39+
command: kubectl apply -f -
40+
args:
41+
stdin: "{{ azimuth_oidc_users_realm_definition | to_nice_yaml }}"
42+
vars:
43+
azimuth_oidc_users_realm_definition:
44+
apiVersion: identity.azimuth.stackhpc.com/v1alpha1
45+
kind: Realm
46+
metadata:
47+
name: "{{ azimuth_oidc_users_realm_name }}"
48+
namespace: "{{ azimuth_release_namespace }}"
49+
50+
- name: Wait for Azimuth users realm to become ready
51+
command: >-
52+
kubectl wait realm {{ azimuth_oidc_users_realm_name }}
53+
--for=jsonpath='{.status.phase}'=Ready
54+
--namespace {{ azimuth_release_namespace }}
55+
--timeout=0
56+
changed_when: false
57+
register: azimuth_oidc_users_realm_ready
58+
until: azimuth_oidc_users_realm_ready is succeeded
59+
# Retry every 5s for 5m
60+
retries: 60
61+
delay: 5
62+
63+
- block:
64+
- name: Ensure OIDC client exists for Azimuth
65+
command: kubectl apply -f -
66+
args:
67+
stdin: "{{ azimuth_oidc_users_realm_definition | to_nice_yaml }}"
68+
vars:
69+
azimuth_oidc_users_realm_definition:
70+
apiVersion: identity.azimuth.stackhpc.com/v1alpha1
71+
kind: OIDCClient
72+
metadata:
73+
name: "{{ azimuth_oidc_client_id }}"
74+
namespace: "{{ azimuth_release_namespace }}"
75+
spec: "{{ azimuth_oidc_client_spec }}"
76+
77+
- name: Wait for Azimuth OIDC client to become ready
78+
command: >-
79+
kubectl wait oidcclient {{ azimuth_oidc_client_id }}
80+
--for=jsonpath='{.status.phase}'=Ready
81+
--namespace {{ azimuth_release_namespace }}
82+
--timeout=0
83+
changed_when: false
84+
register: azimuth_oidc_users_realm_ready
85+
until: azimuth_oidc_users_realm_ready is succeeded
86+
# Retry every 5s for 5m
87+
retries: 60
88+
delay: 5
89+
90+
- name: Get credentials secret name for Azimuth OIDC client
91+
command: >-
92+
kubectl get oidcclient {{ azimuth_oidc_client_id }}
93+
--namespace {{ azimuth_release_namespace }}
94+
--output go-template={% raw %}'{{.status.credentialsSecretName}}'{% endraw %}
95+
register: azimuth_oidc_client_credentials_secret_name
96+
changed_when: false
97+
98+
- name: Get credentials secret data for Azimuth OIDC client
99+
command: >-
100+
kubectl get secret {{ azimuth_oidc_client_credentials_secret_name.stdout }}
101+
--namespace {{ azimuth_release_namespace }}
102+
--output json
103+
register: azimuth_oidc_client_credentials_secret_data
104+
changed_when: false
105+
106+
- name: Set Azimuth OIDC client and secret facts
107+
set_fact:
108+
azimuth_oidc_client_id: >-
109+
{{-
110+
azimuth_oidc_client_credentials_secret_data.stdout |
111+
from_json |
112+
json_query('data."client-id"') |
113+
b64decode
114+
}}
115+
azimuth_oidc_client_secret: >-
116+
{{-
117+
azimuth_oidc_client_credentials_secret_data.stdout |
118+
from_json |
119+
json_query('data."client-secret"') |
120+
b64decode
121+
}}
122+
when:
123+
- azimuth_oidc_client_secret is not defined
124+
125+
- name: Get issuer URL for Azimuth users realm
126+
command: >-
127+
kubectl get realm {{ azimuth_oidc_users_realm_name }}
128+
--namespace {{ azimuth_release_namespace }}
129+
--output go-template={% raw %}'{{.status.oidcIssuerUrl}}'{% endraw %}
130+
register: azimuth_oidc_users_realm_issuer_url
131+
changed_when: false
132+
133+
# This MUST be the last task in the block as it makes the block condition false
134+
# which means all subsequent tasks in the block are skipped, because a block is
135+
# just syntactic sugar for adding a condition to all the tasks
136+
- name: Set Azimuth OIDC issuer URL fact
137+
set_fact:
138+
azimuth_oidc_issuer_url: "{{ azimuth_oidc_users_realm_issuer_url.stdout }}"
139+
when:
140+
- azimuth_authentication_type == "oidc"
141+
- not azimuth_oidc_issuer_url
142+
37143
- name: Install Azimuth on target Kubernetes cluster
38144
kubernetes.core.helm:
39145
chart_ref: "{{ azimuth_chart_name }}"

0 commit comments

Comments
 (0)