This document is for an unreleased version of Crossplane.

This document applies to the Crossplane master branch and not to the latest release v1.14.

Connect Crossplane to AWS to create and manage cloud resources from Kubernetes with the Upbound AWS Provider.

This guide is in two parts:

  • Part 1 walks through installing Crossplane, configuring the provider to authenticate to AWS and creating a Managed Resource in AWS directly from your Kubernetes cluster. This shows Crossplane can communicate with AWS.
  • 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 AWS account with permissions to create an S3 storage bucket
  • AWS access keys

Install Crossplane

Crossplane installs into an existing Kubernetes cluster.

Tip
If you don’t have a Kubernetes cluster create one locally with Kind.

Install the Crossplane Helm chart

Helm enables Crossplane to install all its Kubernetes components through a Helm Chart.

Enable the Crossplane Helm Chart repository:

1helm repo add \
2crossplane-stable https://charts.crossplane.io/stable
3helm repo update

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:231: [debug] CHART PATH: /Users/plumbis/Library/Caches/helm/repository/crossplane-1.14.4.tgz
   8
   9NAME: crossplane
  10LAST DEPLOYED: Fri Dec 15 11:12:42 2023
  11NAMESPACE: crossplane-system
  12STATUS: pending-install
  13REVISION: 1
  14TEST SUITE: None
  15USER-SUPPLIED VALUES:
  16{}
  17
  18COMPUTED VALUES:
  19affinity: {}
  20args: []
  21configuration:
  22  packages: []
  23customAnnotations: {}
  24customLabels: {}
  25deploymentStrategy: RollingUpdate
  26extraEnvVarsCrossplane: {}
  27extraEnvVarsRBACManager: {}
  28extraObjects: []
  29extraVolumeMountsCrossplane: {}
  30extraVolumesCrossplane: {}
  31hostNetwork: false
  32image:
  33  pullPolicy: IfNotPresent
  34  repository: xpkg.upbound.io/crossplane/crossplane
  35  tag: ""
  36imagePullSecrets: {}
  37leaderElection: true
  38metrics:
  39  enabled: false
  40nodeSelector: {}
  41packageCache:
  42  configMap: ""
  43  medium: ""
  44  pvc: ""
  45  sizeLimit: 20Mi
  46podSecurityContextCrossplane: {}
  47podSecurityContextRBACManager: {}
  48priorityClassName: ""
  49provider:
  50  packages: []
  51rbacManager:
  52  affinity: {}
  53  args: []
  54  deploy: true
  55  leaderElection: true
  56  nodeSelector: {}
  57  replicas: 1
  58  skipAggregatedClusterRoles: false
  59  tolerations: []
  60registryCaBundleConfig:
  61  key: ""
  62  name: ""
  63replicas: 1
  64resourcesCrossplane:
  65  limits:
  66    cpu: 100m
  67    memory: 512Mi
  68  requests:
  69    cpu: 100m
  70    memory: 256Mi
  71resourcesRBACManager:
  72  limits:
  73    cpu: 100m
  74    memory: 512Mi
  75  requests:
  76    cpu: 100m
  77    memory: 256Mi
  78securityContextCrossplane:
  79  allowPrivilegeEscalation: false
  80  readOnlyRootFilesystem: true
  81  runAsGroup: 65532
  82  runAsUser: 65532
  83securityContextRBACManager:
  84  allowPrivilegeEscalation: false
  85  readOnlyRootFilesystem: true
  86  runAsGroup: 65532
  87  runAsUser: 65532
  88serviceAccount:
  89  customAnnotations: {}
  90tolerations: []
  91webhooks:
  92  enabled: true
  93
  94HOOKS:
  95MANIFEST:
  96---
  97# Source: crossplane/templates/rbac-manager-serviceaccount.yaml
  98apiVersion: v1
  99kind: ServiceAccount
 100metadata:
 101  name: rbac-manager
 102  namespace: crossplane-system
 103  labels:
 104    app: crossplane
 105    helm.sh/chart: crossplane-1.14.4
 106    app.kubernetes.io/managed-by: Helm
 107    app.kubernetes.io/component: cloud-infrastructure-controller
 108    app.kubernetes.io/part-of: crossplane
 109    app.kubernetes.io/name: crossplane
 110    app.kubernetes.io/instance: crossplane
 111    app.kubernetes.io/version: "1.14.4"
 112---
 113# Source: crossplane/templates/serviceaccount.yaml
 114apiVersion: v1
 115kind: ServiceAccount
 116metadata:
 117  name: crossplane
 118  namespace: crossplane-system
 119  labels:
 120    app: crossplane
 121    helm.sh/chart: crossplane-1.14.4
 122    app.kubernetes.io/managed-by: Helm
 123    app.kubernetes.io/component: cloud-infrastructure-controller
 124    app.kubernetes.io/part-of: crossplane
 125    app.kubernetes.io/name: crossplane
 126    app.kubernetes.io/instance: crossplane
 127    app.kubernetes.io/version: "1.14.4"
 128---
 129# Source: crossplane/templates/secret.yaml
 130# The reason this is created empty and filled by the init container is we want
 131# to manage the lifecycle of the secret via Helm. This way whenever Crossplane
 132# is deleted, the secret is deleted as well.
 133apiVersion: v1
 134kind: Secret
 135metadata:
 136  name: crossplane-root-ca
 137  namespace: crossplane-system
 138type: Opaque
 139---
 140# Source: crossplane/templates/secret.yaml
 141# The reason this is created empty and filled by the init container is we want
 142# to manage the lifecycle of the secret via Helm. This way whenever Crossplane
 143# is deleted, the secret is deleted as well.
 144apiVersion: v1
 145kind: Secret
 146metadata:
 147  name: crossplane-tls-server
 148  namespace: crossplane-system
 149type: Opaque
 150---
 151# Source: crossplane/templates/secret.yaml
 152# The reason this is created empty and filled by the init container is we want
 153# to manage the lifecycle of the secret via Helm. This way whenever Crossplane
 154# is deleted, the secret is deleted as well.
 155apiVersion: v1
 156kind: Secret
 157metadata:
 158  name: crossplane-tls-client
 159  namespace: crossplane-system
 160type: Opaque
 161---
 162# Source: crossplane/templates/clusterrole.yaml
 163apiVersion: rbac.authorization.k8s.io/v1
 164kind: ClusterRole
 165metadata:
 166  name: crossplane
 167  labels:
 168    app: crossplane
 169    helm.sh/chart: crossplane-1.14.4
 170    app.kubernetes.io/managed-by: Helm
 171    app.kubernetes.io/component: cloud-infrastructure-controller
 172    app.kubernetes.io/part-of: crossplane
 173    app.kubernetes.io/name: crossplane
 174    app.kubernetes.io/instance: crossplane
 175    app.kubernetes.io/version: "1.14.4"
 176aggregationRule:
 177  clusterRoleSelectors:
 178  - matchLabels:
 179      rbac.crossplane.io/aggregate-to-crossplane: "true"
 180---
 181# Source: crossplane/templates/clusterrole.yaml
 182apiVersion: rbac.authorization.k8s.io/v1
 183kind: ClusterRole
 184metadata:
 185  name: crossplane:system:aggregate-to-crossplane
 186  labels:
 187    app: crossplane
 188    helm.sh/chart: crossplane-1.14.4
 189    app.kubernetes.io/managed-by: Helm
 190    app.kubernetes.io/component: cloud-infrastructure-controller
 191    app.kubernetes.io/part-of: crossplane
 192    app.kubernetes.io/name: crossplane
 193    app.kubernetes.io/instance: crossplane
 194    app.kubernetes.io/version: "1.14.4"
 195    crossplane.io/scope: "system"
 196    rbac.crossplane.io/aggregate-to-crossplane: "true"
 197rules:
 198- apiGroups:
 199  - ""
 200  resources:
 201  - events
 202  verbs:
 203  - create
 204  - update
 205  - patch
 206  - delete
 207- apiGroups:
 208  - apiextensions.k8s.io
 209  resources:
 210  - customresourcedefinitions
 211  - customresourcedefinitions/status
 212  verbs:
 213  - "*"
 214- apiGroups:
 215  - ""
 216  resources:
 217  - secrets
 218  verbs:
 219  - get
 220  - list
 221  - watch
 222  - create
 223  - update
 224  - patch
 225  - delete
 226- apiGroups:
 227  - ""
 228  resources:
 229  - serviceaccounts
 230  - services
 231  verbs:
 232  - "*"
 233- apiGroups:
 234  - apiextensions.crossplane.io
 235  - pkg.crossplane.io
 236  - secrets.crossplane.io
 237  resources:
 238  - "*"
 239  verbs:
 240  - "*"
 241- apiGroups:
 242  - extensions
 243  - apps
 244  resources:
 245  - deployments
 246  verbs:
 247  - get
 248  - list
 249  - create
 250  - update
 251  - patch
 252  - delete
 253  - watch
 254- apiGroups:
 255  - ""
 256  - coordination.k8s.io
 257  resources:
 258  - configmaps
 259  - leases
 260  verbs:
 261  - get
 262  - list
 263  - create
 264  - update
 265  - patch
 266  - watch
 267  - delete
 268- apiGroups:
 269  - admissionregistration.k8s.io
 270  resources:
 271  - validatingwebhookconfigurations
 272  - mutatingwebhookconfigurations
 273  verbs:
 274  - get
 275  - list
 276  - create
 277  - update
 278  - patch
 279  - watch
 280  - delete
 281---
 282# Source: crossplane/templates/rbac-manager-allowed-provider-permissions.yaml
 283apiVersion: rbac.authorization.k8s.io/v1
 284kind: ClusterRole
 285metadata:
 286  name: crossplane:allowed-provider-permissions
 287  labels:
 288    app: crossplane
 289    helm.sh/chart: crossplane-1.14.4
 290    app.kubernetes.io/managed-by: Helm
 291    app.kubernetes.io/component: cloud-infrastructure-controller
 292    app.kubernetes.io/part-of: crossplane
 293    app.kubernetes.io/name: crossplane
 294    app.kubernetes.io/instance: crossplane
 295    app.kubernetes.io/version: "1.14.4"
 296aggregationRule:
 297  clusterRoleSelectors:
 298  - matchLabels:
 299      rbac.crossplane.io/aggregate-to-allowed-provider-permissions: "true"
 300---
 301# Source: crossplane/templates/rbac-manager-clusterrole.yaml
 302apiVersion: rbac.authorization.k8s.io/v1
 303kind: ClusterRole
 304metadata:
 305  name: crossplane-rbac-manager
 306  labels:
 307    app: crossplane
 308    helm.sh/chart: crossplane-1.14.4
 309    app.kubernetes.io/managed-by: Helm
 310    app.kubernetes.io/component: cloud-infrastructure-controller
 311    app.kubernetes.io/part-of: crossplane
 312    app.kubernetes.io/name: crossplane
 313    app.kubernetes.io/instance: crossplane
 314    app.kubernetes.io/version: "1.14.4"
 315rules:
 316- apiGroups:
 317  - ""
 318  resources:
 319  - events
 320  verbs:
 321  - create
 322  - update
 323  - patch
 324  - delete
 325- apiGroups:
 326  - ""
 327  resources:
 328  - namespaces
 329  verbs:
 330  - get
 331  - list
 332  - watch
 333- apiGroups:
 334    - apps
 335  resources:
 336    - deployments
 337  verbs:
 338    - get
 339    - list
 340    - watch
 341# The RBAC manager creates a series of RBAC roles for each namespace it sees.
 342# These RBAC roles are controlled (in the owner reference sense) by the namespace.
 343# The RBAC manager needs permission to set finalizers on Namespaces in order to
 344# create resources that block their deletion when the
 345# OwnerReferencesPermissionEnforcement admission controller is enabled.
 346# See https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#ownerreferencespermissionenforcement
 347- apiGroups:
 348  - ""
 349  resources:
 350  - namespaces/finalizers
 351  verbs:
 352  - update
 353- apiGroups:
 354  - apiextensions.crossplane.io
 355  resources:
 356  - compositeresourcedefinitions
 357  verbs:
 358  - get
 359  - list
 360  - watch
 361# The RBAC manager creates a series of RBAC cluster roles for each XRD it sees.
 362# These cluster roles are controlled (in the owner reference sense) by the XRD.
 363# The RBAC manager needs permission to set finalizers on XRDs in order to
 364# create resources that block their deletion when the
 365# OwnerReferencesPermissionEnforcement admission controller is enabled.
 366# See https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#ownerreferencespermissionenforcement
 367- apiGroups:
 368  - apiextensions.crossplane.io
 369  resources:
 370  - compositeresourcedefinitions/finalizers
 371  verbs:
 372  - update
 373- apiGroups:
 374  - pkg.crossplane.io
 375  resources:
 376  - providerrevisions
 377  verbs:
 378  - get
 379  - list
 380  - watch
 381# The RBAC manager creates a series of RBAC cluster roles for each ProviderRevision
 382# it sees. These cluster roles are controlled (in the owner reference sense) by the
 383# ProviderRevision. The RBAC manager needs permission to set finalizers on
 384# ProviderRevisions in order to create resources that block their deletion when the
 385# OwnerReferencesPermissionEnforcement admission controller is enabled.
 386# See https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#ownerreferencespermissionenforcement
 387- apiGroups:
 388  - pkg.crossplane.io
 389  resources:
 390  - providerrevisions/finalizers
 391  verbs:
 392  - update
 393- apiGroups:
 394  - apiextensions.k8s.io
 395  resources:
 396  - customresourcedefinitions
 397  verbs:
 398  - get
 399  - list
 400  - watch
 401- apiGroups:
 402  - rbac.authorization.k8s.io
 403  resources:
 404  - clusterroles
 405  - roles
 406  verbs:
 407  - get
 408  - list
 409  - watch
 410  - create
 411  - update
 412  - patch
 413  # The RBAC manager may grant access it does not have.
 414  - escalate
 415- apiGroups:
 416  - rbac.authorization.k8s.io
 417  resources:
 418  - clusterroles
 419  verbs:
 420  - bind
 421- apiGroups:
 422  - rbac.authorization.k8s.io
 423  resources:
 424  - clusterrolebindings
 425  verbs:
 426  - "*"
 427- apiGroups:
 428  - ""
 429  - coordination.k8s.io
 430  resources:
 431  - configmaps
 432  - leases
 433  verbs:
 434  - get
 435  - list
 436  - create
 437  - update
 438  - patch
 439  - watch
 440  - delete
 441---
 442# Source: crossplane/templates/rbac-manager-managed-clusterroles.yaml
 443apiVersion: rbac.authorization.k8s.io/v1
 444kind: ClusterRole
 445metadata:
 446  name: crossplane-admin
 447  labels:
 448    app: crossplane
 449    helm.sh/chart: crossplane-1.14.4
 450    app.kubernetes.io/managed-by: Helm
 451    app.kubernetes.io/component: cloud-infrastructure-controller
 452    app.kubernetes.io/part-of: crossplane
 453    app.kubernetes.io/name: crossplane
 454    app.kubernetes.io/instance: crossplane
 455    app.kubernetes.io/version: "1.14.4"
 456aggregationRule:
 457  clusterRoleSelectors:
 458  - matchLabels:
 459      rbac.crossplane.io/aggregate-to-admin: "true"
 460---
 461# Source: crossplane/templates/rbac-manager-managed-clusterroles.yaml
 462apiVersion: rbac.authorization.k8s.io/v1
 463kind: ClusterRole
 464metadata:
 465  name: crossplane-edit
 466  labels:
 467    app: crossplane
 468    helm.sh/chart: crossplane-1.14.4
 469    app.kubernetes.io/managed-by: Helm
 470    app.kubernetes.io/component: cloud-infrastructure-controller
 471    app.kubernetes.io/part-of: crossplane
 472    app.kubernetes.io/name: crossplane
 473    app.kubernetes.io/instance: crossplane
 474    app.kubernetes.io/version: "1.14.4"
 475aggregationRule:
 476  clusterRoleSelectors:
 477  - matchLabels:
 478      rbac.crossplane.io/aggregate-to-edit: "true"
 479---
 480# Source: crossplane/templates/rbac-manager-managed-clusterroles.yaml
 481apiVersion: rbac.authorization.k8s.io/v1
 482kind: ClusterRole
 483metadata:
 484  name: crossplane-view
 485  labels:
 486    app: crossplane
 487    helm.sh/chart: crossplane-1.14.4
 488    app.kubernetes.io/managed-by: Helm
 489    app.kubernetes.io/component: cloud-infrastructure-controller
 490    app.kubernetes.io/part-of: crossplane
 491    app.kubernetes.io/name: crossplane
 492    app.kubernetes.io/instance: crossplane
 493    app.kubernetes.io/version: "1.14.4"
 494aggregationRule:
 495  clusterRoleSelectors:
 496  - matchLabels:
 497      rbac.crossplane.io/aggregate-to-view: "true"
 498---
 499# Source: crossplane/templates/rbac-manager-managed-clusterroles.yaml
 500apiVersion: rbac.authorization.k8s.io/v1
 501kind: ClusterRole
 502metadata:
 503  name: crossplane-browse
 504  labels:
 505    app: crossplane
 506    helm.sh/chart: crossplane-1.14.4
 507    app.kubernetes.io/managed-by: Helm
 508    app.kubernetes.io/component: cloud-infrastructure-controller
 509    app.kubernetes.io/part-of: crossplane
 510    app.kubernetes.io/name: crossplane
 511    app.kubernetes.io/instance: crossplane
 512    app.kubernetes.io/version: "1.14.4"
 513aggregationRule:
 514  clusterRoleSelectors:
 515  - matchLabels:
 516      rbac.crossplane.io/aggregate-to-browse: "true"
 517---
 518# Source: crossplane/templates/rbac-manager-managed-clusterroles.yaml
 519apiVersion: rbac.authorization.k8s.io/v1
 520kind: ClusterRole
 521metadata:
 522  name: crossplane:aggregate-to-admin
 523  labels:
 524    rbac.crossplane.io/aggregate-to-admin: "true"
 525    app: crossplane
 526    helm.sh/chart: crossplane-1.14.4
 527    app.kubernetes.io/managed-by: Helm
 528    app.kubernetes.io/component: cloud-infrastructure-controller
 529    app.kubernetes.io/part-of: crossplane
 530    app.kubernetes.io/name: crossplane
 531    app.kubernetes.io/instance: crossplane
 532    app.kubernetes.io/version: "1.14.4"
 533rules:
 534# Crossplane administrators have access to view events.
 535- apiGroups: [""]
 536  resources: [events]
 537  verbs: [get, list, watch]
 538# Crossplane administrators must create provider credential secrets, and may
 539# need to read or otherwise interact with connection secrets. They may also need
 540# to create or annotate namespaces.
 541- apiGroups: [""]
 542  resources: [secrets, namespaces]
 543  verbs: ["*"]
 544# Crossplane administrators have access to view the roles that they may be able
 545# to grant to other subjects.
 546- apiGroups: [rbac.authorization.k8s.io]
 547  resources: [clusterroles, roles]
 548  verbs: [get, list, watch]
 549# Crossplane administrators have access to grant the access they have to other
 550# subjects.
 551- apiGroups: [rbac.authorization.k8s.io]
 552  resources: [clusterrolebindings, rolebindings]
 553  verbs: ["*"]
 554# Crossplane administrators have full access to built in Crossplane types.
 555- apiGroups:
 556  - apiextensions.crossplane.io
 557  resources: ["*"]
 558  verbs: ["*"]
 559- apiGroups:
 560  - pkg.crossplane.io
 561  resources: ["*"]
 562  verbs: ["*"]
 563# Crossplane administrators have access to view CRDs in order to debug XRDs.
 564- apiGroups: [apiextensions.k8s.io]
 565  resources: [customresourcedefinitions]
 566  verbs: [get, list, watch]
 567---
 568# Source: crossplane/templates/rbac-manager-managed-clusterroles.yaml
 569apiVersion: rbac.authorization.k8s.io/v1
 570kind: ClusterRole
 571metadata:
 572  name: crossplane:aggregate-to-edit
 573  labels:
 574    rbac.crossplane.io/aggregate-to-edit: "true"
 575    app: crossplane
 576    helm.sh/chart: crossplane-1.14.4
 577    app.kubernetes.io/managed-by: Helm
 578    app.kubernetes.io/component: cloud-infrastructure-controller
 579    app.kubernetes.io/part-of: crossplane
 580    app.kubernetes.io/name: crossplane
 581    app.kubernetes.io/instance: crossplane
 582    app.kubernetes.io/version: "1.14.4"
 583rules:
 584# Crossplane editors have access to view events.
 585- apiGroups: [""]
 586  resources: [events]
 587  verbs: [get, list, watch]
 588# Crossplane editors must create provider credential secrets, and may need to
 589# read or otherwise interact with connection secrets.
 590- apiGroups: [""]
 591  resources: [secrets]
 592  verbs: ["*"]
 593# Crossplane editors may see which namespaces exist, but not edit them.
 594- apiGroups: [""]
 595  resources: [namespaces]
 596  verbs: [get, list, watch]
 597# Crossplane editors have full access to built in Crossplane types.
 598- apiGroups:
 599  - apiextensions.crossplane.io
 600  resources: ["*"]
 601  verbs: ["*"]
 602- apiGroups:
 603  - pkg.crossplane.io
 604  resources: ["*"]
 605  verbs: ["*"]
 606---
 607# Source: crossplane/templates/rbac-manager-managed-clusterroles.yaml
 608apiVersion: rbac.authorization.k8s.io/v1
 609kind: ClusterRole
 610metadata:
 611  name: crossplane:aggregate-to-view
 612  labels:
 613    rbac.crossplane.io/aggregate-to-view: "true"
 614    app: crossplane
 615    helm.sh/chart: crossplane-1.14.4
 616    app.kubernetes.io/managed-by: Helm
 617    app.kubernetes.io/component: cloud-infrastructure-controller
 618    app.kubernetes.io/part-of: crossplane
 619    app.kubernetes.io/name: crossplane
 620    app.kubernetes.io/instance: crossplane
 621    app.kubernetes.io/version: "1.14.4"
 622rules:
 623# Crossplane viewers have access to view events.
 624- apiGroups: [""]
 625  resources: [events]
 626  verbs: [get, list, watch]
 627# Crossplane viewers may see which namespaces exist.
 628- apiGroups: [""]
 629  resources: [namespaces]
 630  verbs: [get, list, watch]
 631# Crossplane viewers have read-only access to built in Crossplane types.
 632- apiGroups:
 633  - apiextensions.crossplane.io
 634  resources: ["*"]
 635  verbs: [get, list, watch]
 636- apiGroups:
 637  - pkg.crossplane.io
 638  resources: ["*"]
 639  verbs: [get, list, watch]
 640---
 641# Source: crossplane/templates/rbac-manager-managed-clusterroles.yaml
 642apiVersion: rbac.authorization.k8s.io/v1
 643kind: ClusterRole
 644metadata:
 645  name: crossplane:aggregate-to-browse
 646  labels:
 647    rbac.crossplane.io/aggregate-to-browse: "true"
 648    app: crossplane
 649    helm.sh/chart: crossplane-1.14.4
 650    app.kubernetes.io/managed-by: Helm
 651    app.kubernetes.io/component: cloud-infrastructure-controller
 652    app.kubernetes.io/part-of: crossplane
 653    app.kubernetes.io/name: crossplane
 654    app.kubernetes.io/instance: crossplane
 655    app.kubernetes.io/version: "1.14.4"
 656rules:
 657# Crossplane browsers have access to view events.
 658- apiGroups: [""]
 659  resources: [events]
 660  verbs: [get, list, watch]
 661# Crossplane browsers have read-only access to compositions and XRDs. This
 662# allows them to discover and select an appropriate composition when creating a
 663# resource claim.
 664- apiGroups:
 665  - apiextensions.crossplane.io
 666  resources: ["*"]
 667  verbs: [get, list, watch]
 668---
 669# Source: crossplane/templates/rbac-manager-managed-clusterroles.yaml
 670# The below ClusterRoles are aggregated to the namespaced RBAC roles created by
 671# the Crossplane RBAC manager when it is running in --manage=All mode.
 672apiVersion: rbac.authorization.k8s.io/v1
 673kind: ClusterRole
 674metadata:
 675  name: crossplane:aggregate-to-ns-admin
 676  labels:
 677    rbac.crossplane.io/aggregate-to-ns-admin: "true"
 678    rbac.crossplane.io/base-of-ns-admin: "true"
 679    app: crossplane
 680    helm.sh/chart: crossplane-1.14.4
 681    app.kubernetes.io/managed-by: Helm
 682    app.kubernetes.io/component: cloud-infrastructure-controller
 683    app.kubernetes.io/part-of: crossplane
 684    app.kubernetes.io/name: crossplane
 685    app.kubernetes.io/instance: crossplane
 686    app.kubernetes.io/version: "1.14.4"
 687rules:
 688# Crossplane namespace admins have access to view events.
 689- apiGroups: [""]
 690  resources: [events]
 691  verbs: [get, list, watch]
 692# Crossplane namespace admins may need to read or otherwise interact with
 693# resource claim connection secrets.
 694- apiGroups: [""]
 695  resources: [secrets]
 696  verbs: ["*"]
 697# Crossplane namespace admins have access to view the roles that they may be
 698# able to grant to other subjects.
 699- apiGroups: [rbac.authorization.k8s.io]
 700  resources: [roles]
 701  verbs: [get, list, watch]
 702# Crossplane namespace admins have access to grant the access they have to other
 703# subjects.
 704- apiGroups: [rbac.authorization.k8s.io]
 705  resources: [rolebindings]
 706  verbs: ["*"]
 707---
 708# Source: crossplane/templates/rbac-manager-managed-clusterroles.yaml
 709apiVersion: rbac.authorization.k8s.io/v1
 710kind: ClusterRole
 711metadata:
 712  name: crossplane:aggregate-to-ns-edit
 713  labels:
 714    rbac.crossplane.io/aggregate-to-ns-edit: "true"
 715    rbac.crossplane.io/base-of-ns-edit: "true"
 716    app: crossplane
 717    helm.sh/chart: crossplane-1.14.4
 718    app.kubernetes.io/managed-by: Helm
 719    app.kubernetes.io/component: cloud-infrastructure-controller
 720    app.kubernetes.io/part-of: crossplane
 721    app.kubernetes.io/name: crossplane
 722    app.kubernetes.io/instance: crossplane
 723    app.kubernetes.io/version: "1.14.4"
 724rules:
 725# Crossplane namespace editors have access to view events.
 726- apiGroups: [""]
 727  resources: [events]
 728  verbs: [get, list, watch]
 729# Crossplane namespace editors may need to read or otherwise interact with
 730# resource claim connection secrets.
 731- apiGroups: [""]
 732  resources: [secrets]
 733  verbs: ["*"]
 734---
 735# Source: crossplane/templates/rbac-manager-managed-clusterroles.yaml
 736apiVersion: rbac.authorization.k8s.io/v1
 737kind: ClusterRole
 738metadata:
 739  name: crossplane:aggregate-to-ns-view
 740  labels:
 741    rbac.crossplane.io/aggregate-to-ns-view: "true"
 742    rbac.crossplane.io/base-of-ns-view: "true"
 743    app: crossplane
 744    helm.sh/chart: crossplane-1.14.4
 745    app.kubernetes.io/managed-by: Helm
 746    app.kubernetes.io/component: cloud-infrastructure-controller
 747    app.kubernetes.io/part-of: crossplane
 748    app.kubernetes.io/name: crossplane
 749    app.kubernetes.io/instance: crossplane
 750    app.kubernetes.io/version: "1.14.4"
 751rules:
 752# Crossplane namespace viewers have access to view events.
 753- apiGroups: [""]
 754  resources: [events]
 755  verbs: [get, list, watch]
 756---
 757# Source: crossplane/templates/clusterrolebinding.yaml
 758apiVersion: rbac.authorization.k8s.io/v1
 759kind: ClusterRoleBinding
 760metadata:
 761  name: crossplane
 762  labels:
 763    app: crossplane
 764    helm.sh/chart: crossplane-1.14.4
 765    app.kubernetes.io/managed-by: Helm
 766    app.kubernetes.io/component: cloud-infrastructure-controller
 767    app.kubernetes.io/part-of: crossplane
 768    app.kubernetes.io/name: crossplane
 769    app.kubernetes.io/instance: crossplane
 770    app.kubernetes.io/version: "1.14.4"
 771roleRef:
 772  apiGroup: rbac.authorization.k8s.io
 773  kind: ClusterRole
 774  name: crossplane
 775subjects:
 776- kind: ServiceAccount
 777  name: crossplane
 778  namespace: crossplane-system
 779---
 780# Source: crossplane/templates/rbac-manager-clusterrolebinding.yaml
 781apiVersion: rbac.authorization.k8s.io/v1
 782kind: ClusterRoleBinding
 783metadata:
 784  name: crossplane-rbac-manager
 785  labels:
 786    app: crossplane
 787    helm.sh/chart: crossplane-1.14.4
 788    app.kubernetes.io/managed-by: Helm
 789    app.kubernetes.io/component: cloud-infrastructure-controller
 790    app.kubernetes.io/part-of: crossplane
 791    app.kubernetes.io/name: crossplane
 792    app.kubernetes.io/instance: crossplane
 793    app.kubernetes.io/version: "1.14.4"
 794roleRef:
 795  apiGroup: rbac.authorization.k8s.io
 796  kind: ClusterRole
 797  name: crossplane-rbac-manager
 798subjects:
 799- kind: ServiceAccount
 800  name: rbac-manager
 801  namespace: crossplane-system
 802---
 803# Source: crossplane/templates/rbac-manager-managed-clusterroles.yaml
 804apiVersion: rbac.authorization.k8s.io/v1
 805kind: ClusterRoleBinding
 806metadata:
 807  name: crossplane-admin
 808  labels:
 809    app: crossplane
 810    helm.sh/chart: crossplane-1.14.4
 811    app.kubernetes.io/managed-by: Helm
 812    app.kubernetes.io/component: cloud-infrastructure-controller
 813    app.kubernetes.io/part-of: crossplane
 814    app.kubernetes.io/name: crossplane
 815    app.kubernetes.io/instance: crossplane
 816    app.kubernetes.io/version: "1.14.4"
 817roleRef:
 818  apiGroup: rbac.authorization.k8s.io
 819  kind: ClusterRole
 820  name: crossplane-admin
 821subjects:
 822- apiGroup: rbac.authorization.k8s.io
 823  kind: Group
 824  name: crossplane:masters
 825---
 826# Source: crossplane/templates/service.yaml
 827apiVersion: v1
 828kind: Service
 829metadata:
 830  name: crossplane-webhooks
 831  namespace: crossplane-system
 832  labels:
 833    app: crossplane
 834    release: crossplane
 835    helm.sh/chart: crossplane-1.14.4
 836    app.kubernetes.io/managed-by: Helm
 837    app.kubernetes.io/component: cloud-infrastructure-controller
 838    app.kubernetes.io/part-of: crossplane
 839    app.kubernetes.io/name: crossplane
 840    app.kubernetes.io/instance: crossplane
 841    app.kubernetes.io/version: "1.14.4"
 842spec:
 843  selector:
 844    app: crossplane
 845    release: crossplane
 846  ports:
 847  - protocol: TCP
 848    port: 9443
 849    targetPort: 9443
 850---
 851# Source: crossplane/templates/deployment.yaml
 852apiVersion: apps/v1
 853kind: Deployment
 854metadata:
 855  name: crossplane
 856  namespace: crossplane-system
 857  labels:
 858    app: crossplane
 859    release: crossplane
 860    helm.sh/chart: crossplane-1.14.4
 861    app.kubernetes.io/managed-by: Helm
 862    app.kubernetes.io/component: cloud-infrastructure-controller
 863    app.kubernetes.io/part-of: crossplane
 864    app.kubernetes.io/name: crossplane
 865    app.kubernetes.io/instance: crossplane
 866    app.kubernetes.io/version: "1.14.4"
 867spec:
 868  replicas: 1
 869  selector:
 870    matchLabels:
 871      app: crossplane
 872      release: crossplane
 873  strategy:
 874    type: RollingUpdate
 875  template:
 876    metadata:
 877      labels:
 878        app: crossplane
 879        release: crossplane
 880        helm.sh/chart: crossplane-1.14.4
 881        app.kubernetes.io/managed-by: Helm
 882        app.kubernetes.io/component: cloud-infrastructure-controller
 883        app.kubernetes.io/part-of: crossplane
 884        app.kubernetes.io/name: crossplane
 885        app.kubernetes.io/instance: crossplane
 886        app.kubernetes.io/version: "1.14.4"
 887    spec:
 888      serviceAccountName: crossplane
 889      hostNetwork: false
 890      initContainers:
 891        - image: "xpkg.upbound.io/crossplane/crossplane:v1.14.4"
 892          args:
 893          - core
 894          - init
 895          imagePullPolicy: IfNotPresent
 896          name: crossplane-init
 897          resources:
 898            limits:
 899              cpu: 100m
 900              memory: 512Mi
 901            requests:
 902              cpu: 100m
 903              memory: 256Mi
 904          securityContext:
 905            allowPrivilegeEscalation: false
 906            readOnlyRootFilesystem: true
 907            runAsGroup: 65532
 908            runAsUser: 65532
 909          env:
 910          - name: GOMAXPROCS
 911            valueFrom:
 912              resourceFieldRef:
 913                containerName: crossplane-init
 914                resource: limits.cpu
 915                divisor: "1"
 916          - name: GOMEMLIMIT
 917            valueFrom:
 918              resourceFieldRef:
 919                containerName: crossplane-init
 920                resource: limits.memory
 921                divisor: "1"
 922          - name: POD_NAMESPACE
 923            valueFrom:
 924              fieldRef:
 925                fieldPath: metadata.namespace
 926          - name: POD_SERVICE_ACCOUNT
 927            valueFrom:
 928              fieldRef:
 929                fieldPath: spec.serviceAccountName
 930          - name: "WEBHOOK_SERVICE_NAME"
 931            value: crossplane-webhooks
 932          - name: "WEBHOOK_SERVICE_NAMESPACE"
 933            valueFrom:
 934              fieldRef:
 935                fieldPath: metadata.namespace
 936          - name: "WEBHOOK_SERVICE_PORT"
 937            value: "9443"
 938          - name: "TLS_CA_SECRET_NAME"
 939            value: crossplane-root-ca
 940          - name: "TLS_SERVER_SECRET_NAME"
 941            value: crossplane-tls-server
 942          - name: "TLS_CLIENT_SECRET_NAME"
 943            value: crossplane-tls-client
 944      containers:
 945      - image: "xpkg.upbound.io/crossplane/crossplane:v1.14.4"
 946        args:
 947        - core
 948        - start
 949        imagePullPolicy: IfNotPresent
 950        name: crossplane
 951        resources:
 952            limits:
 953              cpu: 100m
 954              memory: 512Mi
 955            requests:
 956              cpu: 100m
 957              memory: 256Mi
 958        startupProbe:
 959          failureThreshold: 30
 960          periodSeconds: 2
 961          tcpSocket:
 962            port: readyz
 963        ports:
 964        - name: readyz
 965          containerPort: 8081
 966        - name: webhooks
 967          containerPort: 9443
 968        securityContext:
 969            allowPrivilegeEscalation: false
 970            readOnlyRootFilesystem: true
 971            runAsGroup: 65532
 972            runAsUser: 65532
 973        env:
 974          - name: GOMAXPROCS
 975            valueFrom:
 976              resourceFieldRef:
 977                containerName: crossplane
 978                resource: limits.cpu
 979          - name: GOMEMLIMIT
 980            valueFrom:
 981              resourceFieldRef:
 982                containerName: crossplane
 983                resource: limits.memory
 984          - name: POD_NAMESPACE
 985            valueFrom:
 986              fieldRef:
 987                fieldPath: metadata.namespace
 988          - name: POD_SERVICE_ACCOUNT
 989            valueFrom:
 990              fieldRef:
 991                fieldPath: spec.serviceAccountName
 992          - name: LEADER_ELECTION
 993            value: "true"
 994          - name: "TLS_SERVER_SECRET_NAME"
 995            value: crossplane-tls-server
 996          - name: "TLS_SERVER_CERTS_DIR"
 997            value: /tls/server
 998          - name: "TLS_CLIENT_SECRET_NAME"
 999            value: crossplane-tls-client
1000          - name: "TLS_CLIENT_CERTS_DIR"
1001            value: /tls/client
1002        volumeMounts:
1003          - mountPath: /cache
1004            name: package-cache
1005          - mountPath: /tls/server
1006            name: tls-server-certs
1007          - mountPath: /tls/client
1008            name: tls-client-certs
1009      volumes:
1010      - name: package-cache
1011        emptyDir:
1012          medium:
1013          sizeLimit: 20Mi
1014      - name: tls-server-certs
1015        secret:
1016          secretName: crossplane-tls-server
1017      - name: tls-client-certs
1018        secret:
1019          secretName: crossplane-tls-client
1020---
1021# Source: crossplane/templates/rbac-manager-deployment.yaml
1022apiVersion: apps/v1
1023kind: Deployment
1024metadata:
1025  name: crossplane-rbac-manager
1026  namespace: crossplane-system
1027  labels:
1028    app: crossplane-rbac-manager
1029    release: crossplane
1030    helm.sh/chart: crossplane-1.14.4
1031    app.kubernetes.io/managed-by: Helm
1032    app.kubernetes.io/component: cloud-infrastructure-controller
1033    app.kubernetes.io/part-of: crossplane
1034    app.kubernetes.io/name: crossplane
1035    app.kubernetes.io/instance: crossplane
1036    app.kubernetes.io/version: "1.14.4"
1037spec:
1038  replicas: 1
1039  selector:
1040    matchLabels:
1041      app: crossplane-rbac-manager
1042      release: crossplane
1043  strategy:
1044    type: RollingUpdate
1045  template:
1046    metadata:
1047      labels:
1048        app: crossplane-rbac-manager
1049        release: crossplane
1050        helm.sh/chart: crossplane-1.14.4
1051        app.kubernetes.io/managed-by: Helm
1052        app.kubernetes.io/component: cloud-infrastructure-controller
1053        app.kubernetes.io/part-of: crossplane
1054        app.kubernetes.io/name: crossplane
1055        app.kubernetes.io/instance: crossplane
1056        app.kubernetes.io/version: "1.14.4"
1057    spec:
1058      serviceAccountName: rbac-manager
1059      initContainers:
1060      - image: "xpkg.upbound.io/crossplane/crossplane:v1.14.4"
1061        args:
1062        - rbac
1063        - init
1064        imagePullPolicy: IfNotPresent
1065        name: crossplane-init
1066        resources:
1067            limits:
1068              cpu: 100m
1069              memory: 512Mi
1070            requests:
1071              cpu: 100m
1072              memory: 256Mi
1073        securityContext:
1074            allowPrivilegeEscalation: false
1075            readOnlyRootFilesystem: true
1076            runAsGroup: 65532
1077            runAsUser: 65532
1078        env:
1079          - name: GOMAXPROCS
1080            valueFrom:
1081              resourceFieldRef:
1082                containerName: crossplane-init
1083                resource: limits.cpu
1084          - name: GOMEMLIMIT
1085            valueFrom:
1086              resourceFieldRef:
1087                containerName: crossplane-init
1088                resource: limits.memory
1089      containers:
1090      - image: "xpkg.upbound.io/crossplane/crossplane:v1.14.4"
1091        args:
1092        - rbac
1093        - start
1094        - --manage=Basic
1095        - --provider-clusterrole=crossplane:allowed-provider-permissions
1096        imagePullPolicy: IfNotPresent
1097        name: crossplane
1098        resources:
1099            limits:
1100              cpu: 100m
1101              memory: 512Mi
1102            requests:
1103              cpu: 100m
1104              memory: 256Mi
1105        securityContext:
1106            allowPrivilegeEscalation: false
1107            readOnlyRootFilesystem: true
1108            runAsGroup: 65532
1109            runAsUser: 65532
1110        env:
1111          - name: GOMAXPROCS
1112            valueFrom:
1113              resourceFieldRef:
1114                containerName: crossplane
1115                resource: limits.cpu
1116          - name: GOMEMLIMIT
1117            valueFrom:
1118              resourceFieldRef:
1119                containerName: crossplane
1120                resource: limits.memory
1121          - name: LEADER_ELECTION
1122            value: "true"
1123
1124NOTES:
1125Release: crossplane
1126
1127Chart Name: crossplane
1128Chart 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.
1129Chart Version: 1.14.4
1130Chart Application Version: 1.14.4
1131
1132Kube 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 AWS provider

Install the AWS S3 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-aws-s3
6spec:
7  package: xpkg.upbound.io/upbound/provider-aws-s3:v0.47.0
8EOF

The Crossplane Provider installs the Kubernetes Custom Resource Definitions (CRDs) representing AWS S3 services. These CRDs allow you to create AWS resources directly inside Kubernetes.

Verify the provider installed with kubectl get providers.

1kubectl get providers
2NAME                          INSTALLED   HEALTHY   PACKAGE                                               AGE
3provider-aws-s3               True        True      xpkg.upbound.io/upbound/provider-aws-s3:v0.47.0       97s
4upbound-provider-family-aws   True        True      xpkg.upbound.io/upbound/provider-family-aws:v0.47.0   88s

The S3 Provider installs a second Provider, the upbound-provider-family-aws.
The family provider manages authentication to AWS across all AWS family Providers.

You can view the new CRDs with kubectl get crds.
Every CRD maps to a unique AWS service Crossplane can provision and manage.

Tip
See details about all the supported CRDs in the Upbound Marketplace.

Create a Kubernetes secret for AWS

The provider requires credentials to create and manage AWS resources.
Providers use a Kubernetes Secret to connect the credentials to the provider.

Generate a Kubernetes Secret from your AWS key-pair and then configure the Provider to use it.

Generate an AWS key-pair file

For basic user authentication, use an AWS Access keys key-pair file.

Tip
The AWS documentation provides information on how to generate AWS Access keys.

Create a text file containing the AWS account aws_access_key_id and aws_secret_access_key.

1[default]
2aws_access_key_id = 
3aws_secret_access_key = 

Save this text file as aws-credentials.txt.

Tip
The Authentication section of the AWS Provider documentation describes other authentication methods.

Create a Kubernetes secret with the AWS credentials

A Kubernetes generic secret has a name and contents.
Use kubectl create secret
to generate the secret object named aws-secret
in the crossplane-system namespace.

Use the --from-file= argument to set the value to the contents of the aws-credentials.txt file.

1kubectl create secret \
2generic aws-secret \
3-n crossplane-system \
4--from-file=creds=./aws-credentials.txt

View the secret with kubectl describe secret

Tip
The size may be larger if there are extra blank spaces in your text file.
 1kubectl describe secret aws-secret -n crossplane-system
 2Name:         aws-secret
 3Namespace:    crossplane-system
 4Labels:       <none>
 5Annotations:  <none>
 6
 7Type:  Opaque
 8
 9Data
10====
11creds:  114 bytes

Create a ProviderConfig

A ProviderConfig customizes the settings of the AWS Provider.

Apply the ProviderConfig with the this Kubernetes configuration file:

 1cat <<EOF | kubectl apply -f -
 2apiVersion: aws.upbound.io/v1beta1
 3kind: ProviderConfig
 4metadata:
 5  name: default
 6spec:
 7  credentials:
 8    source: Secret
 9    secretRef:
10      namespace: crossplane-system
11      name: aws-secret
12      key: creds
13EOF

This attaches the AWS credentials, saved as a Kubernetes secret, as a secretRef.

The spec.credentials.secretRef.name value is the name of the Kubernetes secret containing the AWS credentials in the spec.credentials.secretRef.namespace.

Create a managed resource

A managed resource is anything Crossplane creates and manages outside of the Kubernetes cluster.

This guide creates an AWS S3 bucket with Crossplane.

The S3 bucket is a managed resource.

Tip
AWS S3 bucket names must be globally unique. To generate a unique name the example uses a random hash. Any unique name is acceptable.
 1cat <<EOF | kubectl create -f -
 2apiVersion: s3.aws.upbound.io/v1beta1
 3kind: Bucket
 4metadata:
 5  generateName: crossplane-bucket-
 6spec:
 7  forProvider:
 8    region: us-east-2
 9  providerConfigRef:
10    name: default
11EOF

The apiVersion and kind are from the provider’s CRDs.

The metadata.name value is the name of the created S3 bucket in AWS.
This example uses the generated name crossplane-bucket-<hash> in the $bucket variable.

The spec.forProvider.region tells AWS which AWS region to use when deploying resources.

The region can be any AWS Regional endpoint code.

Use kubectl get buckets to verify Crossplane created the bucket.

Tip
Crossplane created the bucket when the values READY and SYNCED are True.
This may take up to 5 minutes.
1kubectl get buckets
2NAME                      READY   SYNCED   EXTERNAL-NAME             AGE
3crossplane-bucket-hhdzh   True    True     crossplane-bucket-hhdzh   5s

Delete the managed resource

Before shutting down your Kubernetes cluster, delete the S3 bucket just created.

Use kubectl delete bucket <bucketname> to remove the bucket.

1kubectl delete bucket crossplane-bucket-hhdzh
2bucket.s3.aws.upbound.io "crossplane-bucket-hhdzh" deleted

Next steps