Azure Quickstart
Connect Crossplane to Azure to create and manage cloud resources from Kubernetes with the Upbound Azure Provider.
This guide is in two parts:
- Part 1 walks through installing Crossplane, configuring the provider to authenticate to Azure and creating a Managed Resource in Azure directly from your Kubernetes cluster. This shows Crossplane can communicate with Azure.
- Part 2 shows how to build and access a custom API with Crossplane.
Prerequisites
This quickstart requires:
- a Kubernetes cluster with at least 2 GB of RAM
- permissions to create pods and secrets in the Kubernetes cluster
- Helm version v3.2.0 or later
- an Azure account with permissions to create an Azure Virtual Machine and Virtual Network
- an Azure account with permissions to create an Azure service principal and an Azure resource group
Install Crossplane
Crossplane installs into an existing Kubernetes cluster.
Install the Crossplane Helm chart
Helm enables Crossplane to install all its Kubernetes components through a Helm Chart.
Enable the Crossplane Helm Chart repository:
Run the Helm dry-run to see all the Crossplane components Helm installs.
1helm install crossplane \
2crossplane-stable/crossplane \
3--dry-run --debug \
4--namespace crossplane-system \
5--create-namespace
1helm install crossplane \
2crossplane-stable/crossplane \
3--dry-run --debug \
4--namespace crossplane-system \
5--create-namespace
6install.go:214: [debug] Original chart version: ""
7install.go:216: [debug] setting version to >0.0.0-0
8install.go:231: [debug] CHART PATH: /Users/plumbis/Library/Caches/helm/repository/crossplane-1.15.0.tgz
9
10NAME: crossplane
11LAST DEPLOYED: Mon Feb 12 14:46:15 2024
12NAMESPACE: default
13STATUS: pending-install
14REVISION: 1
15TEST SUITE: None
16USER-SUPPLIED VALUES:
17{}
18
19COMPUTED VALUES:
20affinity: {}
21args: []
22configuration:
23 packages: []
24customAnnotations: {}
25customLabels: {}
26deploymentStrategy: RollingUpdate
27extraEnvVarsCrossplane: {}
28extraEnvVarsRBACManager: {}
29extraObjects: []
30extraVolumeMountsCrossplane: {}
31extraVolumesCrossplane: {}
32hostNetwork: false
33image:
34 pullPolicy: IfNotPresent
35 repository: xpkg.upbound.io/crossplane/crossplane
36 tag: ""
37imagePullSecrets: {}
38leaderElection: true
39metrics:
40 enabled: false
41nodeSelector: {}
42packageCache:
43 configMap: ""
44 medium: ""
45 pvc: ""
46 sizeLimit: 20Mi
47podSecurityContextCrossplane: {}
48podSecurityContextRBACManager: {}
49priorityClassName: ""
50provider:
51 packages: []
52rbacManager:
53 affinity: {}
54 args: []
55 deploy: true
56 leaderElection: true
57 nodeSelector: {}
58 replicas: 1
59 skipAggregatedClusterRoles: false
60 tolerations: []
61registryCaBundleConfig:
62 key: ""
63 name: ""
64replicas: 1
65resourcesCrossplane:
66 limits:
67 cpu: 100m
68 memory: 512Mi
69 requests:
70 cpu: 100m
71 memory: 256Mi
72resourcesRBACManager:
73 limits:
74 cpu: 100m
75 memory: 512Mi
76 requests:
77 cpu: 100m
78 memory: 256Mi
79securityContextCrossplane:
80 allowPrivilegeEscalation: false
81 readOnlyRootFilesystem: true
82 runAsGroup: 65532
83 runAsUser: 65532
84securityContextRBACManager:
85 allowPrivilegeEscalation: false
86 readOnlyRootFilesystem: true
87 runAsGroup: 65532
88 runAsUser: 65532
89serviceAccount:
90 customAnnotations: {}
91tolerations: []
92webhooks:
93 enabled: true
94
95HOOKS:
96MANIFEST:
97---
98# Source: crossplane/templates/rbac-manager-serviceaccount.yaml
99apiVersion: v1
100kind: ServiceAccount
101metadata:
102 name: rbac-manager
103 namespace: default
104 labels:
105 app: crossplane
106 helm.sh/chart: crossplane-1.15.0
107 app.kubernetes.io/managed-by: Helm
108 app.kubernetes.io/component: cloud-infrastructure-controller
109 app.kubernetes.io/part-of: crossplane
110 app.kubernetes.io/name: crossplane
111 app.kubernetes.io/instance: crossplane
112 app.kubernetes.io/version: "1.15.0"
113---
114# Source: crossplane/templates/serviceaccount.yaml
115apiVersion: v1
116kind: ServiceAccount
117metadata:
118 name: crossplane
119 namespace: default
120 labels:
121 app: crossplane
122 helm.sh/chart: crossplane-1.15.0
123 app.kubernetes.io/managed-by: Helm
124 app.kubernetes.io/component: cloud-infrastructure-controller
125 app.kubernetes.io/part-of: crossplane
126 app.kubernetes.io/name: crossplane
127 app.kubernetes.io/instance: crossplane
128 app.kubernetes.io/version: "1.15.0"
129---
130# Source: crossplane/templates/secret.yaml
131# The reason this is created empty and filled by the init container is we want
132# to manage the lifecycle of the secret via Helm. This way whenever Crossplane
133# is deleted, the secret is deleted as well.
134apiVersion: v1
135kind: Secret
136metadata:
137 name: crossplane-root-ca
138 namespace: default
139type: Opaque
140---
141# Source: crossplane/templates/secret.yaml
142# The reason this is created empty and filled by the init container is we want
143# to manage the lifecycle of the secret via Helm. This way whenever Crossplane
144# is deleted, the secret is deleted as well.
145apiVersion: v1
146kind: Secret
147metadata:
148 name: crossplane-tls-server
149 namespace: default
150type: Opaque
151---
152# Source: crossplane/templates/secret.yaml
153# The reason this is created empty and filled by the init container is we want
154# to manage the lifecycle of the secret via Helm. This way whenever Crossplane
155# is deleted, the secret is deleted as well.
156apiVersion: v1
157kind: Secret
158metadata:
159 name: crossplane-tls-client
160 namespace: default
161type: Opaque
162---
163# Source: crossplane/templates/clusterrole.yaml
164apiVersion: rbac.authorization.k8s.io/v1
165kind: ClusterRole
166metadata:
167 name: crossplane
168 labels:
169 app: crossplane
170 helm.sh/chart: crossplane-1.15.0
171 app.kubernetes.io/managed-by: Helm
172 app.kubernetes.io/component: cloud-infrastructure-controller
173 app.kubernetes.io/part-of: crossplane
174 app.kubernetes.io/name: crossplane
175 app.kubernetes.io/instance: crossplane
176 app.kubernetes.io/version: "1.15.0"
177aggregationRule:
178 clusterRoleSelectors:
179 - matchLabels:
180 rbac.crossplane.io/aggregate-to-crossplane: "true"
181---
182# Source: crossplane/templates/clusterrole.yaml
183apiVersion: rbac.authorization.k8s.io/v1
184kind: ClusterRole
185metadata:
186 name: crossplane:system:aggregate-to-crossplane
187 labels:
188 app: crossplane
189 helm.sh/chart: crossplane-1.15.0
190 app.kubernetes.io/managed-by: Helm
191 app.kubernetes.io/component: cloud-infrastructure-controller
192 app.kubernetes.io/part-of: crossplane
193 app.kubernetes.io/name: crossplane
194 app.kubernetes.io/instance: crossplane
195 app.kubernetes.io/version: "1.15.0"
196 crossplane.io/scope: "system"
197 rbac.crossplane.io/aggregate-to-crossplane: "true"
198rules:
199- apiGroups:
200 - ""
201 resources:
202 - events
203 verbs:
204 - create
205 - update
206 - patch
207 - delete
208- apiGroups:
209 - apiextensions.k8s.io
210 resources:
211 - customresourcedefinitions
212 - customresourcedefinitions/status
213 verbs:
214 - "*"
215- apiGroups:
216 - ""
217 resources:
218 - secrets
219 verbs:
220 - get
221 - list
222 - watch
223 - create
224 - update
225 - patch
226 - delete
227- apiGroups:
228 - ""
229 resources:
230 - serviceaccounts
231 - services
232 verbs:
233 - "*"
234- apiGroups:
235 - apiextensions.crossplane.io
236 - pkg.crossplane.io
237 - secrets.crossplane.io
238 resources:
239 - "*"
240 verbs:
241 - "*"
242- apiGroups:
243 - extensions
244 - apps
245 resources:
246 - deployments
247 verbs:
248 - get
249 - list
250 - create
251 - update
252 - patch
253 - delete
254 - watch
255- apiGroups:
256 - ""
257 - coordination.k8s.io
258 resources:
259 - configmaps
260 - leases
261 verbs:
262 - get
263 - list
264 - create
265 - update
266 - patch
267 - watch
268 - delete
269- apiGroups:
270 - admissionregistration.k8s.io
271 resources:
272 - validatingwebhookconfigurations
273 - mutatingwebhookconfigurations
274 verbs:
275 - get
276 - list
277 - create
278 - update
279 - patch
280 - watch
281 - delete
282---
283# Source: crossplane/templates/rbac-manager-allowed-provider-permissions.yaml
284apiVersion: rbac.authorization.k8s.io/v1
285kind: ClusterRole
286metadata:
287 name: crossplane:allowed-provider-permissions
288 labels:
289 app: crossplane
290 helm.sh/chart: crossplane-1.15.0
291 app.kubernetes.io/managed-by: Helm
292 app.kubernetes.io/component: cloud-infrastructure-controller
293 app.kubernetes.io/part-of: crossplane
294 app.kubernetes.io/name: crossplane
295 app.kubernetes.io/instance: crossplane
296 app.kubernetes.io/version: "1.15.0"
297aggregationRule:
298 clusterRoleSelectors:
299 - matchLabels:
300 rbac.crossplane.io/aggregate-to-allowed-provider-permissions: "true"
301---
302# Source: crossplane/templates/rbac-manager-clusterrole.yaml
303apiVersion: rbac.authorization.k8s.io/v1
304kind: ClusterRole
305metadata:
306 name: crossplane-rbac-manager
307 labels:
308 app: crossplane
309 helm.sh/chart: crossplane-1.15.0
310 app.kubernetes.io/managed-by: Helm
311 app.kubernetes.io/component: cloud-infrastructure-controller
312 app.kubernetes.io/part-of: crossplane
313 app.kubernetes.io/name: crossplane
314 app.kubernetes.io/instance: crossplane
315 app.kubernetes.io/version: "1.15.0"
316rules:
317- apiGroups:
318 - ""
319 resources:
320 - events
321 verbs:
322 - create
323 - update
324 - patch
325 - delete
326- apiGroups:
327 - ""
328 resources:
329 - namespaces
330 verbs:
331 - get
332 - list
333 - watch
334- apiGroups:
335 - apps
336 resources:
337 - deployments
338 verbs:
339 - get
340 - list
341 - watch
342# The RBAC manager creates a series of RBAC roles for each namespace it sees.
343# These RBAC roles are controlled (in the owner reference sense) by the namespace.
344# The RBAC manager needs permission to set finalizers on Namespaces in order to
345# create resources that block their deletion when the
346# OwnerReferencesPermissionEnforcement admission controller is enabled.
347# See https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#ownerreferencespermissionenforcement
348- apiGroups:
349 - ""
350 resources:
351 - namespaces/finalizers
352 verbs:
353 - update
354- apiGroups:
355 - apiextensions.crossplane.io
356 resources:
357 - compositeresourcedefinitions
358 verbs:
359 - get
360 - list
361 - watch
362# The RBAC manager creates a series of RBAC cluster roles for each XRD it sees.
363# These cluster roles are controlled (in the owner reference sense) by the XRD.
364# The RBAC manager needs permission to set finalizers on XRDs in order to
365# create resources that block their deletion when the
366# OwnerReferencesPermissionEnforcement admission controller is enabled.
367# See https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#ownerreferencespermissionenforcement
368- apiGroups:
369 - apiextensions.crossplane.io
370 resources:
371 - compositeresourcedefinitions/finalizers
372 verbs:
373 - update
374- apiGroups:
375 - pkg.crossplane.io
376 resources:
377 - providerrevisions
378 verbs:
379 - get
380 - list
381 - watch
382# The RBAC manager creates a series of RBAC cluster roles for each ProviderRevision
383# it sees. These cluster roles are controlled (in the owner reference sense) by the
384# ProviderRevision. The RBAC manager needs permission to set finalizers on
385# ProviderRevisions in order to create resources that block their deletion when the
386# OwnerReferencesPermissionEnforcement admission controller is enabled.
387# See https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#ownerreferencespermissionenforcement
388- apiGroups:
389 - pkg.crossplane.io
390 resources:
391 - providerrevisions/finalizers
392 verbs:
393 - update
394- apiGroups:
395 - apiextensions.k8s.io
396 resources:
397 - customresourcedefinitions
398 verbs:
399 - get
400 - list
401 - watch
402- apiGroups:
403 - rbac.authorization.k8s.io
404 resources:
405 - clusterroles
406 - roles
407 verbs:
408 - get
409 - list
410 - watch
411 - create
412 - update
413 - patch
414 # The RBAC manager may grant access it does not have.
415 - escalate
416- apiGroups:
417 - rbac.authorization.k8s.io
418 resources:
419 - clusterroles
420 verbs:
421 - bind
422- apiGroups:
423 - rbac.authorization.k8s.io
424 resources:
425 - clusterrolebindings
426 verbs:
427 - "*"
428- apiGroups:
429 - ""
430 - coordination.k8s.io
431 resources:
432 - configmaps
433 - leases
434 verbs:
435 - get
436 - list
437 - create
438 - update
439 - patch
440 - watch
441 - delete
442---
443# Source: crossplane/templates/rbac-manager-managed-clusterroles.yaml
444apiVersion: rbac.authorization.k8s.io/v1
445kind: ClusterRole
446metadata:
447 name: crossplane-admin
448 labels:
449 app: crossplane
450 helm.sh/chart: crossplane-1.15.0
451 app.kubernetes.io/managed-by: Helm
452 app.kubernetes.io/component: cloud-infrastructure-controller
453 app.kubernetes.io/part-of: crossplane
454 app.kubernetes.io/name: crossplane
455 app.kubernetes.io/instance: crossplane
456 app.kubernetes.io/version: "1.15.0"
457aggregationRule:
458 clusterRoleSelectors:
459 - matchLabels:
460 rbac.crossplane.io/aggregate-to-admin: "true"
461---
462# Source: crossplane/templates/rbac-manager-managed-clusterroles.yaml
463apiVersion: rbac.authorization.k8s.io/v1
464kind: ClusterRole
465metadata:
466 name: crossplane-edit
467 labels:
468 app: crossplane
469 helm.sh/chart: crossplane-1.15.0
470 app.kubernetes.io/managed-by: Helm
471 app.kubernetes.io/component: cloud-infrastructure-controller
472 app.kubernetes.io/part-of: crossplane
473 app.kubernetes.io/name: crossplane
474 app.kubernetes.io/instance: crossplane
475 app.kubernetes.io/version: "1.15.0"
476aggregationRule:
477 clusterRoleSelectors:
478 - matchLabels:
479 rbac.crossplane.io/aggregate-to-edit: "true"
480---
481# Source: crossplane/templates/rbac-manager-managed-clusterroles.yaml
482apiVersion: rbac.authorization.k8s.io/v1
483kind: ClusterRole
484metadata:
485 name: crossplane-view
486 labels:
487 app: crossplane
488 helm.sh/chart: crossplane-1.15.0
489 app.kubernetes.io/managed-by: Helm
490 app.kubernetes.io/component: cloud-infrastructure-controller
491 app.kubernetes.io/part-of: crossplane
492 app.kubernetes.io/name: crossplane
493 app.kubernetes.io/instance: crossplane
494 app.kubernetes.io/version: "1.15.0"
495aggregationRule:
496 clusterRoleSelectors:
497 - matchLabels:
498 rbac.crossplane.io/aggregate-to-view: "true"
499---
500# Source: crossplane/templates/rbac-manager-managed-clusterroles.yaml
501apiVersion: rbac.authorization.k8s.io/v1
502kind: ClusterRole
503metadata:
504 name: crossplane-browse
505 labels:
506 app: crossplane
507 helm.sh/chart: crossplane-1.15.0
508 app.kubernetes.io/managed-by: Helm
509 app.kubernetes.io/component: cloud-infrastructure-controller
510 app.kubernetes.io/part-of: crossplane
511 app.kubernetes.io/name: crossplane
512 app.kubernetes.io/instance: crossplane
513 app.kubernetes.io/version: "1.15.0"
514aggregationRule:
515 clusterRoleSelectors:
516 - matchLabels:
517 rbac.crossplane.io/aggregate-to-browse: "true"
518---
519# Source: crossplane/templates/rbac-manager-managed-clusterroles.yaml
520apiVersion: rbac.authorization.k8s.io/v1
521kind: ClusterRole
522metadata:
523 name: crossplane:aggregate-to-admin
524 labels:
525 rbac.crossplane.io/aggregate-to-admin: "true"
526 app: crossplane
527 helm.sh/chart: crossplane-1.15.0
528 app.kubernetes.io/managed-by: Helm
529 app.kubernetes.io/component: cloud-infrastructure-controller
530 app.kubernetes.io/part-of: crossplane
531 app.kubernetes.io/name: crossplane
532 app.kubernetes.io/instance: crossplane
533 app.kubernetes.io/version: "1.15.0"
534rules:
535# Crossplane administrators have access to view events.
536- apiGroups: [""]
537 resources: [events]
538 verbs: [get, list, watch]
539# Crossplane administrators must create provider credential secrets, and may
540# need to read or otherwise interact with connection secrets. They may also need
541# to create or annotate namespaces.
542- apiGroups: [""]
543 resources: [secrets, namespaces]
544 verbs: ["*"]
545# Crossplane administrators have access to view the roles that they may be able
546# to grant to other subjects.
547- apiGroups: [rbac.authorization.k8s.io]
548 resources: [clusterroles, roles]
549 verbs: [get, list, watch]
550# Crossplane administrators have access to grant the access they have to other
551# subjects.
552- apiGroups: [rbac.authorization.k8s.io]
553 resources: [clusterrolebindings, rolebindings]
554 verbs: ["*"]
555# Crossplane administrators have full access to built in Crossplane types.
556- apiGroups:
557 - apiextensions.crossplane.io
558 resources: ["*"]
559 verbs: ["*"]
560- apiGroups:
561 - pkg.crossplane.io
562 resources: ["*"]
563 verbs: ["*"]
564# Crossplane administrators have access to view CRDs in order to debug XRDs.
565- apiGroups: [apiextensions.k8s.io]
566 resources: [customresourcedefinitions]
567 verbs: [get, list, watch]
568---
569# Source: crossplane/templates/rbac-manager-managed-clusterroles.yaml
570apiVersion: rbac.authorization.k8s.io/v1
571kind: ClusterRole
572metadata:
573 name: crossplane:aggregate-to-edit
574 labels:
575 rbac.crossplane.io/aggregate-to-edit: "true"
576 app: crossplane
577 helm.sh/chart: crossplane-1.15.0
578 app.kubernetes.io/managed-by: Helm
579 app.kubernetes.io/component: cloud-infrastructure-controller
580 app.kubernetes.io/part-of: crossplane
581 app.kubernetes.io/name: crossplane
582 app.kubernetes.io/instance: crossplane
583 app.kubernetes.io/version: "1.15.0"
584rules:
585# Crossplane editors have access to view events.
586- apiGroups: [""]
587 resources: [events]
588 verbs: [get, list, watch]
589# Crossplane editors must create provider credential secrets, and may need to
590# read or otherwise interact with connection secrets.
591- apiGroups: [""]
592 resources: [secrets]
593 verbs: ["*"]
594# Crossplane editors may see which namespaces exist, but not edit them.
595- apiGroups: [""]
596 resources: [namespaces]
597 verbs: [get, list, watch]
598# Crossplane editors have full access to built in Crossplane types.
599- apiGroups:
600 - apiextensions.crossplane.io
601 resources: ["*"]
602 verbs: ["*"]
603- apiGroups:
604 - pkg.crossplane.io
605 resources: ["*"]
606 verbs: ["*"]
607---
608# Source: crossplane/templates/rbac-manager-managed-clusterroles.yaml
609apiVersion: rbac.authorization.k8s.io/v1
610kind: ClusterRole
611metadata:
612 name: crossplane:aggregate-to-view
613 labels:
614 rbac.crossplane.io/aggregate-to-view: "true"
615 app: crossplane
616 helm.sh/chart: crossplane-1.15.0
617 app.kubernetes.io/managed-by: Helm
618 app.kubernetes.io/component: cloud-infrastructure-controller
619 app.kubernetes.io/part-of: crossplane
620 app.kubernetes.io/name: crossplane
621 app.kubernetes.io/instance: crossplane
622 app.kubernetes.io/version: "1.15.0"
623rules:
624# Crossplane viewers have access to view events.
625- apiGroups: [""]
626 resources: [events]
627 verbs: [get, list, watch]
628# Crossplane viewers may see which namespaces exist.
629- apiGroups: [""]
630 resources: [namespaces]
631 verbs: [get, list, watch]
632# Crossplane viewers have read-only access to built in Crossplane types.
633- apiGroups:
634 - apiextensions.crossplane.io
635 resources: ["*"]
636 verbs: [get, list, watch]
637- apiGroups:
638 - pkg.crossplane.io
639 resources: ["*"]
640 verbs: [get, list, watch]
641---
642# Source: crossplane/templates/rbac-manager-managed-clusterroles.yaml
643apiVersion: rbac.authorization.k8s.io/v1
644kind: ClusterRole
645metadata:
646 name: crossplane:aggregate-to-browse
647 labels:
648 rbac.crossplane.io/aggregate-to-browse: "true"
649 app: crossplane
650 helm.sh/chart: crossplane-1.15.0
651 app.kubernetes.io/managed-by: Helm
652 app.kubernetes.io/component: cloud-infrastructure-controller
653 app.kubernetes.io/part-of: crossplane
654 app.kubernetes.io/name: crossplane
655 app.kubernetes.io/instance: crossplane
656 app.kubernetes.io/version: "1.15.0"
657rules:
658# Crossplane browsers have access to view events.
659- apiGroups: [""]
660 resources: [events]
661 verbs: [get, list, watch]
662# Crossplane browsers have read-only access to compositions and XRDs. This
663# allows them to discover and select an appropriate composition when creating a
664# resource claim.
665- apiGroups:
666 - apiextensions.crossplane.io
667 resources: ["*"]
668 verbs: [get, list, watch]
669---
670# Source: crossplane/templates/clusterrolebinding.yaml
671apiVersion: rbac.authorization.k8s.io/v1
672kind: ClusterRoleBinding
673metadata:
674 name: crossplane
675 labels:
676 app: crossplane
677 helm.sh/chart: crossplane-1.15.0
678 app.kubernetes.io/managed-by: Helm
679 app.kubernetes.io/component: cloud-infrastructure-controller
680 app.kubernetes.io/part-of: crossplane
681 app.kubernetes.io/name: crossplane
682 app.kubernetes.io/instance: crossplane
683 app.kubernetes.io/version: "1.15.0"
684roleRef:
685 apiGroup: rbac.authorization.k8s.io
686 kind: ClusterRole
687 name: crossplane
688subjects:
689- kind: ServiceAccount
690 name: crossplane
691 namespace: default
692---
693# Source: crossplane/templates/rbac-manager-clusterrolebinding.yaml
694apiVersion: rbac.authorization.k8s.io/v1
695kind: ClusterRoleBinding
696metadata:
697 name: crossplane-rbac-manager
698 labels:
699 app: crossplane
700 helm.sh/chart: crossplane-1.15.0
701 app.kubernetes.io/managed-by: Helm
702 app.kubernetes.io/component: cloud-infrastructure-controller
703 app.kubernetes.io/part-of: crossplane
704 app.kubernetes.io/name: crossplane
705 app.kubernetes.io/instance: crossplane
706 app.kubernetes.io/version: "1.15.0"
707roleRef:
708 apiGroup: rbac.authorization.k8s.io
709 kind: ClusterRole
710 name: crossplane-rbac-manager
711subjects:
712- kind: ServiceAccount
713 name: rbac-manager
714 namespace: default
715---
716# Source: crossplane/templates/rbac-manager-managed-clusterroles.yaml
717apiVersion: rbac.authorization.k8s.io/v1
718kind: ClusterRoleBinding
719metadata:
720 name: crossplane-admin
721 labels:
722 app: crossplane
723 helm.sh/chart: crossplane-1.15.0
724 app.kubernetes.io/managed-by: Helm
725 app.kubernetes.io/component: cloud-infrastructure-controller
726 app.kubernetes.io/part-of: crossplane
727 app.kubernetes.io/name: crossplane
728 app.kubernetes.io/instance: crossplane
729 app.kubernetes.io/version: "1.15.0"
730roleRef:
731 apiGroup: rbac.authorization.k8s.io
732 kind: ClusterRole
733 name: crossplane-admin
734subjects:
735- apiGroup: rbac.authorization.k8s.io
736 kind: Group
737 name: crossplane:masters
738---
739# Source: crossplane/templates/service.yaml
740apiVersion: v1
741kind: Service
742metadata:
743 name: crossplane-webhooks
744 namespace: default
745 labels:
746 app: crossplane
747 release: crossplane
748 helm.sh/chart: crossplane-1.15.0
749 app.kubernetes.io/managed-by: Helm
750 app.kubernetes.io/component: cloud-infrastructure-controller
751 app.kubernetes.io/part-of: crossplane
752 app.kubernetes.io/name: crossplane
753 app.kubernetes.io/instance: crossplane
754 app.kubernetes.io/version: "1.15.0"
755spec:
756 selector:
757 app: crossplane
758 release: crossplane
759 ports:
760 - protocol: TCP
761 port: 9443
762 targetPort: 9443
763---
764# Source: crossplane/templates/deployment.yaml
765apiVersion: apps/v1
766kind: Deployment
767metadata:
768 name: crossplane
769 namespace: default
770 labels:
771 app: crossplane
772 release: crossplane
773 helm.sh/chart: crossplane-1.15.0
774 app.kubernetes.io/managed-by: Helm
775 app.kubernetes.io/component: cloud-infrastructure-controller
776 app.kubernetes.io/part-of: crossplane
777 app.kubernetes.io/name: crossplane
778 app.kubernetes.io/instance: crossplane
779 app.kubernetes.io/version: "1.15.0"
780spec:
781 replicas: 1
782 selector:
783 matchLabels:
784 app: crossplane
785 release: crossplane
786 strategy:
787 type: RollingUpdate
788 template:
789 metadata:
790 labels:
791 app: crossplane
792 release: crossplane
793 helm.sh/chart: crossplane-1.15.0
794 app.kubernetes.io/managed-by: Helm
795 app.kubernetes.io/component: cloud-infrastructure-controller
796 app.kubernetes.io/part-of: crossplane
797 app.kubernetes.io/name: crossplane
798 app.kubernetes.io/instance: crossplane
799 app.kubernetes.io/version: "1.15.0"
800 spec:
801 serviceAccountName: crossplane
802 hostNetwork: false
803 initContainers:
804 - image: "xpkg.upbound.io/crossplane/crossplane:v1.15.0"
805 args:
806 - core
807 - init
808 imagePullPolicy: IfNotPresent
809 name: crossplane-init
810 resources:
811 limits:
812 cpu: 100m
813 memory: 512Mi
814 requests:
815 cpu: 100m
816 memory: 256Mi
817 securityContext:
818 allowPrivilegeEscalation: false
819 readOnlyRootFilesystem: true
820 runAsGroup: 65532
821 runAsUser: 65532
822 env:
823 - name: GOMAXPROCS
824 valueFrom:
825 resourceFieldRef:
826 containerName: crossplane-init
827 resource: limits.cpu
828 divisor: "1"
829 - name: GOMEMLIMIT
830 valueFrom:
831 resourceFieldRef:
832 containerName: crossplane-init
833 resource: limits.memory
834 divisor: "1"
835 - name: POD_NAMESPACE
836 valueFrom:
837 fieldRef:
838 fieldPath: metadata.namespace
839 - name: POD_SERVICE_ACCOUNT
840 valueFrom:
841 fieldRef:
842 fieldPath: spec.serviceAccountName
843 - name: "WEBHOOK_SERVICE_NAME"
844 value: crossplane-webhooks
845 - name: "WEBHOOK_SERVICE_NAMESPACE"
846 valueFrom:
847 fieldRef:
848 fieldPath: metadata.namespace
849 - name: "WEBHOOK_SERVICE_PORT"
850 value: "9443"
851 - name: "TLS_CA_SECRET_NAME"
852 value: crossplane-root-ca
853 - name: "TLS_SERVER_SECRET_NAME"
854 value: crossplane-tls-server
855 - name: "TLS_CLIENT_SECRET_NAME"
856 value: crossplane-tls-client
857 containers:
858 - image: "xpkg.upbound.io/crossplane/crossplane:v1.15.0"
859 args:
860 - core
861 - start
862 imagePullPolicy: IfNotPresent
863 name: crossplane
864 resources:
865 limits:
866 cpu: 100m
867 memory: 512Mi
868 requests:
869 cpu: 100m
870 memory: 256Mi
871 startupProbe:
872 failureThreshold: 30
873 periodSeconds: 2
874 tcpSocket:
875 port: readyz
876 ports:
877 - name: readyz
878 containerPort: 8081
879 - name: webhooks
880 containerPort: 9443
881 securityContext:
882 allowPrivilegeEscalation: false
883 readOnlyRootFilesystem: true
884 runAsGroup: 65532
885 runAsUser: 65532
886 env:
887 - name: GOMAXPROCS
888 valueFrom:
889 resourceFieldRef:
890 containerName: crossplane
891 resource: limits.cpu
892 divisor: "1"
893 - name: GOMEMLIMIT
894 valueFrom:
895 resourceFieldRef:
896 containerName: crossplane
897 resource: limits.memory
898 divisor: "1"
899 - name: POD_NAMESPACE
900 valueFrom:
901 fieldRef:
902 fieldPath: metadata.namespace
903 - name: POD_SERVICE_ACCOUNT
904 valueFrom:
905 fieldRef:
906 fieldPath: spec.serviceAccountName
907 - name: LEADER_ELECTION
908 value: "true"
909 - name: "TLS_SERVER_SECRET_NAME"
910 value: crossplane-tls-server
911 - name: "TLS_SERVER_CERTS_DIR"
912 value: /tls/server
913 - name: "TLS_CLIENT_SECRET_NAME"
914 value: crossplane-tls-client
915 - name: "TLS_CLIENT_CERTS_DIR"
916 value: /tls/client
917 volumeMounts:
918 - mountPath: /cache
919 name: package-cache
920 - mountPath: /tls/server
921 name: tls-server-certs
922 - mountPath: /tls/client
923 name: tls-client-certs
924 volumes:
925 - name: package-cache
926 emptyDir:
927 medium:
928 sizeLimit: 20Mi
929 - name: tls-server-certs
930 secret:
931 secretName: crossplane-tls-server
932 - name: tls-client-certs
933 secret:
934 secretName: crossplane-tls-client
935---
936# Source: crossplane/templates/rbac-manager-deployment.yaml
937apiVersion: apps/v1
938kind: Deployment
939metadata:
940 name: crossplane-rbac-manager
941 namespace: default
942 labels:
943 app: crossplane-rbac-manager
944 release: crossplane
945 helm.sh/chart: crossplane-1.15.0
946 app.kubernetes.io/managed-by: Helm
947 app.kubernetes.io/component: cloud-infrastructure-controller
948 app.kubernetes.io/part-of: crossplane
949 app.kubernetes.io/name: crossplane
950 app.kubernetes.io/instance: crossplane
951 app.kubernetes.io/version: "1.15.0"
952spec:
953 replicas: 1
954 selector:
955 matchLabels:
956 app: crossplane-rbac-manager
957 release: crossplane
958 strategy:
959 type: RollingUpdate
960 template:
961 metadata:
962 labels:
963 app: crossplane-rbac-manager
964 release: crossplane
965 helm.sh/chart: crossplane-1.15.0
966 app.kubernetes.io/managed-by: Helm
967 app.kubernetes.io/component: cloud-infrastructure-controller
968 app.kubernetes.io/part-of: crossplane
969 app.kubernetes.io/name: crossplane
970 app.kubernetes.io/instance: crossplane
971 app.kubernetes.io/version: "1.15.0"
972 spec:
973 serviceAccountName: rbac-manager
974 initContainers:
975 - image: "xpkg.upbound.io/crossplane/crossplane:v1.15.0"
976 args:
977 - rbac
978 - init
979 imagePullPolicy: IfNotPresent
980 name: crossplane-init
981 resources:
982 limits:
983 cpu: 100m
984 memory: 512Mi
985 requests:
986 cpu: 100m
987 memory: 256Mi
988 securityContext:
989 allowPrivilegeEscalation: false
990 readOnlyRootFilesystem: true
991 runAsGroup: 65532
992 runAsUser: 65532
993 env:
994 - name: GOMAXPROCS
995 valueFrom:
996 resourceFieldRef:
997 containerName: crossplane-init
998 resource: limits.cpu
999 - name: GOMEMLIMIT
1000 valueFrom:
1001 resourceFieldRef:
1002 containerName: crossplane-init
1003 resource: limits.memory
1004 containers:
1005 - image: "xpkg.upbound.io/crossplane/crossplane:v1.15.0"
1006 args:
1007 - rbac
1008 - start
1009 - --provider-clusterrole=crossplane:allowed-provider-permissions
1010 imagePullPolicy: IfNotPresent
1011 name: crossplane
1012 resources:
1013 limits:
1014 cpu: 100m
1015 memory: 512Mi
1016 requests:
1017 cpu: 100m
1018 memory: 256Mi
1019 securityContext:
1020 allowPrivilegeEscalation: false
1021 readOnlyRootFilesystem: true
1022 runAsGroup: 65532
1023 runAsUser: 65532
1024 env:
1025 - name: GOMAXPROCS
1026 valueFrom:
1027 resourceFieldRef:
1028 containerName: crossplane
1029 resource: limits.cpu
1030 - name: GOMEMLIMIT
1031 valueFrom:
1032 resourceFieldRef:
1033 containerName: crossplane
1034 resource: limits.memory
1035 - name: LEADER_ELECTION
1036 value: "true"
1037
1038NOTES:
1039Release: crossplane
1040
1041Chart Name: crossplane
1042Chart Description: Crossplane is an open source Kubernetes add-on that enables platform teams to assemble infrastructure from multiple vendors, and expose higher level self-service APIs for application teams to consume.
1043Chart Version: 1.15.0
1044Chart Application Version: 1.15.0
1045
1046Kube Version: v1.27.3
Install the Crossplane components using helm install
.
1helm install crossplane \
2crossplane-stable/crossplane \
3--namespace crossplane-system \
4--create-namespace
Verify Crossplane installed with kubectl get pods
.
1kubectl get pods -n crossplane-system
2NAME READY STATUS RESTARTS AGE
3crossplane-d4cd8d784-ldcgb 1/1 Running 0 54s
4crossplane-rbac-manager-84769b574-6mw6f 1/1 Running 0 54s
Installing Crossplane creates new Kubernetes API end-points.
Look at the new API end-points with kubectl api-resources | grep crossplane
.
1kubectl api-resources | grep crossplane
2compositeresourcedefinitions xrd,xrds apiextensions.crossplane.io/v1 false CompositeResourceDefinition
3compositionrevisions comprev apiextensions.crossplane.io/v1 false CompositionRevision
4compositions comp apiextensions.crossplane.io/v1 false Composition
5environmentconfigs envcfg apiextensions.crossplane.io/v1alpha1 false EnvironmentConfig
6usages apiextensions.crossplane.io/v1alpha1 false Usage
7configurationrevisions pkg.crossplane.io/v1 false ConfigurationRevision
8configurations pkg.crossplane.io/v1 false Configuration
9controllerconfigs pkg.crossplane.io/v1alpha1 false ControllerConfig
10deploymentruntimeconfigs pkg.crossplane.io/v1beta1 false DeploymentRuntimeConfig
11functionrevisions pkg.crossplane.io/v1beta1 false FunctionRevision
12functions pkg.crossplane.io/v1beta1 false Function
13locks pkg.crossplane.io/v1beta1 false Lock
14providerrevisions pkg.crossplane.io/v1 false ProviderRevision
15providers pkg.crossplane.io/v1 false Provider
16storeconfigs secrets.crossplane.io/v1alpha1 false StoreConfig
Install the Azure provider
Install the Azure Network resource provider into the Kubernetes cluster with a Kubernetes configuration file.
1cat <<EOF | kubectl apply -f -
2apiVersion: pkg.crossplane.io/v1
3kind: Provider
4metadata:
5 name: provider-azure-network
6spec:
7 package: xpkg.upbound.io/upbound/provider-azure-network:v0.42.1
8EOF
The Crossplane
installs the Kubernetes Custom Resource Definitions (CRDs) representing Azure Networking
services. These CRDs allow you to create Azure resources directly inside
Kubernetes.
Verify the provider installed with kubectl get providers
.
1kubectl get providers
2NAME INSTALLED HEALTHY PACKAGE AGE
3provider-azure-network True True xpkg.upbound.io/upbound/provider-azure-network:v0.42.1 38s
4upbound-provider-family-azure True True xpkg.upbound.io/upbound/provider-family-azure:v0.42.1 26s
The Network Provider installs a second Provider, the
provider.
The family provider manages authentication to Azure across all Azure family
Providers.
You can view the new CRDs with kubectl get crds
.
Every CRD maps to a unique Azure service Crossplane can provision and manage.
Create a Kubernetes secret for Azure
The provider requires credentials to create and manage Azure resources. Providers use a Kubernetes Secret to connect the credentials to the provider.
This guide generates an Azure service principal JSON file and saves it as a Kubernetes Secret.
Install the Azure command-line
Generating an authentication file requires the Azure command-line.
Follow the documentation from Microsoft to Download and install the Azure command-line.
Log in to the Azure command-line.
az login
Create an Azure service principal
Follow the Azure documentation to find your Subscription ID from the Azure Portal.
Using the Azure command-line and provide your Subscription ID create a service principal and authentication file.
Save your Azure JSON output as azure-credentials.json
.
Create a Kubernetes secret with the Azure credentials
A Kubernetes generic secret has a name and contents. Use
to generate the secret object named
in the
namespace.
Use the
argument to set the value to the contents of the
file.
1kubectl create secret \
2generic azure-secret \
3-n crossplane-system \
4--from-file=creds=./azure-credentials.json
View the secret with kubectl describe secret
1kubectl describe secret azure-secret -n crossplane-system
2Name: azure-secret
3Namespace: crossplane-system
4Labels: <none>
5Annotations: <none>
6
7Type: Opaque
8
9Data
10====
11creds: 629 bytes
Create a ProviderConfig
A ProviderConfig
customizes the settings of the Azure Provider.
Apply the
with the command:
1cat <<EOF | kubectl apply -f -
2apiVersion: azure.upbound.io/v1beta1
3metadata:
4 name: default
5kind: ProviderConfig
6spec:
7 credentials:
8 source: Secret
9 secretRef:
10 namespace: crossplane-system
11 name: azure-secret
12 key: creds
13EOF
This attaches the Azure credentials, saved as a Kubernetes secret, as a
.
The
value is the name of the Kubernetes secret containing the Azure credentials in the
.
Create a managed resource
A managed resource is anything Crossplane creates and manages outside of the Kubernetes cluster. This example creates an Azure Virtual Network with Crossplane. The Virtual Network is a managed resource.
1cat <<EOF | kubectl create -f -
2apiVersion: network.azure.upbound.io/v1beta1
3kind: VirtualNetwork
4metadata:
5 name: crossplane-quickstart-network
6spec:
7 forProvider:
8 addressSpace:
9 - 10.0.0.0/16
10 location: "Sweden Central"
11 resourceGroupName: docs
12EOF
The
and
are from the provider’s CRDs.
The
tells Azure which location to use when deploying the resource.
Use kubectl get virtualnetwork.network
to verify Crossplane created the
Azure Virtual Network.
READY
and SYNCED
are True
.This may take up to 5 minutes.
1kubectl get virtualnetwork.network
2NAME READY SYNCED EXTERNAL-NAME AGE
3crossplane-quickstart-network True True crossplane-quickstart-network 10m
Delete the managed resource
Before shutting down your Kubernetes cluster, delete the virtual network just created.
Use kubectl delete virtualnetwork.network
to delete the virtual network.
1kubectl delete virtualnetwork.network crossplane-quickstart-network
2virtualnetwork.network.azure.upbound.io "crossplane-quickstart-network" deleted
Next steps
- Continue to part 2 to create and use a custom API with Crossplane.
- Explore Azure resources that Crossplane can configure in the Provider CRD reference.
- Join the Crossplane Slack and connect with Crossplane users and contributors.