├── Assets └── conf.png ├── README.md ├── aws-creds.conf ├── aws-eks.yaml ├── crossplane-config ├── config-k8s.yaml ├── provider-aws.yaml ├── provider-config-aws.yaml ├── provider-helm.yaml └── provider-kubernetes.yaml └── packages └── k8s ├── README.md ├── crossplane.yaml ├── definition.yaml └── eks.yaml /Assets/conf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cem-altuner/crossplane-prod-ready-eks/14fb99eab80477dccaec473d537900980e2e85b0/Assets/conf.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Production-Ready Amazon EKS cluster using Crossplane 2 | 3 | This example shows how to create production-ready EKS CLuster using the Crossplane. 4 | 5 | ### Prerequisites 6 | Please make sure to install the following tools on your machine before moving on. 7 | - Minikube, Kind, or EKS Cluster 8 | - Kubectl 9 | 10 | 11 | The figure below provides an overview of the configuration of the demo. 12 | 13 | 14 | 15 | First create a namespaces `crossplane-system` and `team-a` with the following command: 16 | 17 | After creating the "crossplane-system" namespace, write your AWS credentials to `aws-creds.conf` file and create a secret with the following command. 18 | ``` 19 | kubectl -n crossplane-system \ 20 | create secret generic aws-creds \ 21 | --from-file creds=./aws-creds.conf 22 | ``` 23 | 24 | After these steps are completed, Install the necessary tools and configuration files with the following commands. 25 | ``` 26 | helm upgrade --install \ 27 | crossplane crossplane-stable/crossplane \ 28 | --namespace crossplane-system \ 29 | --create-namespace \ 30 | --wait 31 | ``` 32 | ``` 33 | kubectl apply \ 34 | --filename crossplane-config/provider-aws.yaml 35 | ``` 36 | ``` 37 | kubectl apply \ 38 | --filename crossplane-config/provider-config-aws.yaml 39 | ``` 40 | 41 | > :warning: If the output is "unable to recognize," wait a couple of seconds and re-run the previous command! 42 | ``` 43 | kubectl apply \ 44 | --filename crossplane-config/provider-helm.yaml 45 | ``` 46 | ``` 47 | kubectl apply \ 48 | --filename crossplane-config/provider-kubernetes.yaml 49 | ``` 50 | ``` 51 | kubectl apply \ 52 | --filename crossplane-config/config-k8s.yaml 53 | ``` 54 | 55 | Run the following command and wait until all packages are ready. 56 | ``` 57 | kubectl get pkgrev 58 | ``` 59 | 60 | Now it is time to provision our production-ready EKS cluster. Use the "aws-eks.yaml" file to provision the EKS cluster with the following command. 61 | ``` 62 | kubectl -n team-a apply -f aws-eks.yaml 63 | ``` 64 | 65 | The last step is to get the “kubeconfig” file to use our EKS cluster. Run the following commands to get and set the “kubeconfig” file. 66 | 67 | ``` 68 | kubectl --namespace crossplane-system \ 69 | get secret team-a-eks-cluster \ 70 | --output jsonpath="{.data.kubeconfig}" \ 71 | | base64 -d >kubeconfig.yaml 72 | 73 | export KUBECONFIG=$PWD/kubeconfig.yaml 74 | ``` 75 | 76 | ## Destroy 77 | 78 | Run the following command to destroy your resources. 79 | 80 | ``` 81 | unset KUBECONFIG 82 | 83 | kubectl --namespace team-a delete \ 84 | --filename examples/aws-eks.yaml 85 | ``` 86 | -------------------------------------------------------------------------------- /aws-creds.conf: -------------------------------------------------------------------------------- 1 | [default] 2 | aws_access_key_id = 3 | aws_secret_access_key = 4 | 5 | -------------------------------------------------------------------------------- /aws-eks.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: prodready.cluster/v1alpha1 2 | kind: ClusterClaim 3 | metadata: 4 | name: team-a-eks 5 | labels: 6 | cluster-owner: cem 7 | spec: 8 | id: team-a-eks 9 | compositionSelector: 10 | matchLabels: 11 | provider: aws 12 | cluster: eks 13 | parameters: 14 | nodeSize: small 15 | minNodeCount: 3 16 | -------------------------------------------------------------------------------- /crossplane-config/config-k8s.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | apiVersion: pkg.crossplane.io/v1 4 | kind: Configuration 5 | metadata: 6 | name: crossplane-k8s 7 | spec: 8 | package: cemaltuner/crossplane-k8s:v0.2.14 9 | -------------------------------------------------------------------------------- /crossplane-config/provider-aws.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | apiVersion: pkg.crossplane.io/v1 4 | kind: Provider 5 | metadata: 6 | name: crossplane-provider-aws 7 | spec: 8 | package: crossplane/provider-aws:v0.22.0 9 | -------------------------------------------------------------------------------- /crossplane-config/provider-config-aws.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | apiVersion: aws.crossplane.io/v1beta1 4 | kind: ProviderConfig 5 | metadata: 6 | name: default 7 | spec: 8 | credentials: 9 | source: Secret 10 | secretRef: 11 | namespace: crossplane-system 12 | name: aws-creds 13 | key: creds 14 | -------------------------------------------------------------------------------- /crossplane-config/provider-helm.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: pkg.crossplane.io/v1 2 | kind: Provider 3 | metadata: 4 | name: crossplane-provider-helm 5 | spec: 6 | package: crossplane/provider-helm:v0.9.0 7 | -------------------------------------------------------------------------------- /crossplane-config/provider-kubernetes.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: pkg.crossplane.io/v1 2 | kind: Provider 3 | metadata: 4 | name: crossplane-provider-kubernetes 5 | spec: 6 | package: crossplane/provider-kubernetes:main 7 | -------------------------------------------------------------------------------- /packages/k8s/README.md: -------------------------------------------------------------------------------- 1 | Run the following command to build package. 2 | 3 | ``` 4 | kubectl crossplane build configuration \ 5 | --name k8s 6 | ``` 7 | 8 | Run the following command to push your package to dockerhub. 9 | 10 | ``` 11 | kubectl crossplane push configuration \ 12 | /crossplane-k8s:v0.2.14 13 | ``` 14 | 15 | > :warning: It is necessary to login docker before push the package. 16 | -------------------------------------------------------------------------------- /packages/k8s/crossplane.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: meta.pkg.crossplane.io/v1 2 | kind: Configuration 3 | metadata: 4 | name: k8s 5 | spec: 6 | crossplane: 7 | version: ">=v1.6" 8 | dependsOn: 9 | - provider: crossplane/provider-aws 10 | version: v0.22.0 11 | - provider: crossplane/provider-helm 12 | version: v0.9.0 13 | -------------------------------------------------------------------------------- /packages/k8s/definition.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apiextensions.crossplane.io/v1 2 | kind: CompositeResourceDefinition 3 | metadata: 4 | name: compositeclusters.prodready.cluster 5 | spec: 6 | connectionSecretKeys: 7 | - kubeconfig 8 | defaultCompositionRef: 9 | name: cluster-aws 10 | group: prodready.cluster 11 | names: 12 | kind: CompositeCluster 13 | plural: compositeclusters 14 | claimNames: 15 | kind: ClusterClaim 16 | plural: clusterclaims 17 | versions: 18 | - name: v1alpha1 19 | served: true 20 | referenceable: true 21 | schema: 22 | openAPIV3Schema: 23 | type: object 24 | properties: 25 | spec: 26 | type: object 27 | properties: 28 | id: 29 | type: string 30 | description: ID of this Cluster that other objects will use to refer to it. 31 | parameters: 32 | type: object 33 | properties: 34 | version: 35 | description: The Kubernetes version for the cluster. 36 | type: string 37 | nodeSize: 38 | description: The size of the nodes; small, medium, large 39 | type: string 40 | minNodeCount: 41 | description: The minimum number of nodes 42 | type: integer 43 | default: 1 44 | required: 45 | - nodeSize 46 | required: 47 | - id 48 | - parameters 49 | status: 50 | type: object 51 | properties: 52 | clusterName: 53 | description: The name of the cluster 54 | type: string 55 | controlPlaneStatus: 56 | description: The status of the control plane 57 | type: string 58 | nodePoolStatus: 59 | description: The status of the node pool 60 | type: string 61 | additionalPrinterColumns: 62 | - name: clusterName 63 | type: string 64 | jsonPath: ".status.clusterName" 65 | - name: controlPlane 66 | type: string 67 | jsonPath: ".status.controlPlaneStatus" 68 | - name: nodePool 69 | type: string 70 | jsonPath: ".status.nodePoolStatus" 71 | -------------------------------------------------------------------------------- /packages/k8s/eks.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apiextensions.crossplane.io/v1 2 | kind: Composition 3 | metadata: 4 | name: cluster-aws 5 | labels: 6 | provider: aws 7 | cluster: eks 8 | spec: 9 | compositeTypeRef: 10 | apiVersion: prodready.cluster/v1alpha1 11 | kind: CompositeCluster 12 | writeConnectionSecretsToNamespace: crossplane-system 13 | patchSets: 14 | - name: metadata 15 | patches: 16 | - fromFieldPath: metadata.labels 17 | resources: 18 | - name: ekscluster 19 | base: 20 | apiVersion: eks.aws.crossplane.io/v1beta1 21 | kind: Cluster 22 | spec: 23 | forProvider: 24 | region: us-east-1 25 | version: "1.21" 26 | roleArnSelector: 27 | matchControllerRef: true 28 | resourcesVpcConfig: 29 | endpointPrivateAccess: true 30 | endpointPublicAccess: true 31 | subnetIdSelector: 32 | matchControllerRef: true 33 | patches: 34 | - fromFieldPath: spec.id 35 | toFieldPath: metadata.name 36 | - fromFieldPath: spec.parameters.version 37 | toFieldPath: spec.forProvider.version 38 | - fromFieldPath: spec.id 39 | toFieldPath: spec.writeConnectionSecretToRef.name 40 | transforms: 41 | - type: string 42 | string: 43 | fmt: "%s-cluster" 44 | - fromFieldPath: spec.id 45 | toFieldPath: spec.forProvider.roleArnSelector.matchLabels.role 46 | transforms: 47 | - type: string 48 | string: 49 | fmt: "%s-controlplane" 50 | - type: ToCompositeFieldPath 51 | fromFieldPath: metadata.name 52 | toFieldPath: status.clusterName 53 | - type: ToCompositeFieldPath 54 | fromFieldPath: status.atProvider.status 55 | toFieldPath: status.controlPlaneStatus 56 | - fromFieldPath: spec.writeConnectionSecretToRef.namespace 57 | toFieldPath: spec.writeConnectionSecretToRef.namespace 58 | readinessChecks: 59 | - type: MatchString 60 | fieldPath: status.atProvider.status 61 | matchString: ACTIVE 62 | connectionDetails: 63 | - fromConnectionSecretKey: kubeconfig 64 | - name: eksnodegroup 65 | base: 66 | apiVersion: eks.aws.crossplane.io/v1alpha1 67 | kind: NodeGroup 68 | spec: 69 | forProvider: 70 | region: us-east-1 71 | clusterNameSelector: 72 | matchControllerRef: true 73 | nodeRoleSelector: 74 | matchControllerRef: true 75 | subnetSelector: 76 | matchLabels: 77 | access: public 78 | scalingConfig: 79 | minSize: 1 80 | maxSize: 10 81 | desiredSize: 1 82 | instanceTypes: 83 | - t3.small 84 | patches: 85 | - fromFieldPath: spec.id 86 | toFieldPath: metadata.name 87 | - fromFieldPath: spec.parameters.nodeSize 88 | toFieldPath: spec.forProvider.instanceTypes[0] 89 | transforms: 90 | - type: map 91 | map: 92 | small: t3.small 93 | medium: t3.medium 94 | large: t3.large 95 | - fromFieldPath: spec.id 96 | toFieldPath: spec.forProvider.nodeRoleSelector.matchLabels.role 97 | transforms: 98 | - type: string 99 | string: 100 | fmt: "%s-nodegroup" 101 | - fromFieldPath: spec.parameters.minNodeCount 102 | toFieldPath: spec.forProvider.scalingConfig.minSize 103 | - fromFieldPath: spec.parameters.minNodeCount 104 | toFieldPath: spec.forProvider.scalingConfig.desiredSize 105 | - type: ToCompositeFieldPath 106 | fromFieldPath: status.atProvider.status 107 | toFieldPath: status.nodePoolStatus 108 | readinessChecks: 109 | - type: MatchString 110 | fieldPath: status.atProvider.status 111 | matchString: ACTIVE 112 | - name: iamrole-controlplane 113 | base: 114 | apiVersion: iam.aws.crossplane.io/v1beta1 115 | kind: Role 116 | spec: 117 | forProvider: 118 | assumeRolePolicyDocument: | 119 | { 120 | "Version": "2012-10-17", 121 | "Statement": [ 122 | { 123 | "Effect": "Allow", 124 | "Principal": { 125 | "Service": [ 126 | "eks.amazonaws.com" 127 | ] 128 | }, 129 | "Action": [ 130 | "sts:AssumeRole" 131 | ] 132 | } 133 | ] 134 | } 135 | patches: 136 | - fromFieldPath: spec.id 137 | toFieldPath: metadata.name 138 | transforms: 139 | - type: string 140 | string: 141 | fmt: "%s-controlplane" 142 | - fromFieldPath: spec.id 143 | toFieldPath: metadata.labels.role 144 | transforms: 145 | - type: string 146 | string: 147 | fmt: "%s-controlplane" 148 | - name: iamrole-nodegroup 149 | base: 150 | apiVersion: iam.aws.crossplane.io/v1beta1 151 | kind: Role 152 | spec: 153 | forProvider: 154 | assumeRolePolicyDocument: | 155 | { 156 | "Version": "2012-10-17", 157 | "Statement": [ 158 | { 159 | "Effect": "Allow", 160 | "Principal": { 161 | "Service": [ 162 | "ec2.amazonaws.com" 163 | ] 164 | }, 165 | "Action": [ 166 | "sts:AssumeRole" 167 | ] 168 | } 169 | ] 170 | } 171 | patches: 172 | - fromFieldPath: spec.id 173 | toFieldPath: metadata.name 174 | transforms: 175 | - type: string 176 | string: 177 | fmt: "%s-nodegroup" 178 | - fromFieldPath: spec.id 179 | toFieldPath: metadata.labels.role 180 | transforms: 181 | - type: string 182 | string: 183 | fmt: "%s-nodegroup" 184 | - name: iamattachment-controlplane 185 | base: 186 | apiVersion: iam.aws.crossplane.io/v1beta1 187 | kind: RolePolicyAttachment 188 | spec: 189 | forProvider: 190 | policyArn: arn:aws:iam::aws:policy/AmazonEKSClusterPolicy 191 | roleNameSelector: 192 | matchControllerRef: true 193 | patches: 194 | - fromFieldPath: spec.id 195 | toFieldPath: metadata.name 196 | transforms: 197 | - type: string 198 | string: 199 | fmt: "%s-controlplane" 200 | - fromFieldPath: spec.id 201 | toFieldPath: spec.forProvider.roleNameSelector.matchLabels.role 202 | transforms: 203 | - type: string 204 | string: 205 | fmt: "%s-controlplane" 206 | - name: iamattachment-service 207 | base: 208 | apiVersion: iam.aws.crossplane.io/v1beta1 209 | kind: RolePolicyAttachment 210 | spec: 211 | forProvider: 212 | policyArn: arn:aws:iam::aws:policy/AmazonEKSServicePolicy 213 | roleNameSelector: 214 | matchControllerRef: true 215 | patches: 216 | - fromFieldPath: spec.id 217 | toFieldPath: metadata.name 218 | transforms: 219 | - type: string 220 | string: 221 | fmt: "%s-service" 222 | - fromFieldPath: spec.id 223 | toFieldPath: spec.forProvider.roleNameSelector.matchLabels.role 224 | transforms: 225 | - type: string 226 | string: 227 | fmt: "%s-controlplane" 228 | - name: iamattachment-worker 229 | base: 230 | apiVersion: iam.aws.crossplane.io/v1beta1 231 | kind: RolePolicyAttachment 232 | spec: 233 | forProvider: 234 | policyArn: arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy 235 | roleNameSelector: 236 | matchControllerRef: true 237 | patches: 238 | - fromFieldPath: spec.id 239 | toFieldPath: metadata.name 240 | transforms: 241 | - type: string 242 | string: 243 | fmt: "%s-worker" 244 | - fromFieldPath: spec.id 245 | toFieldPath: spec.forProvider.roleNameSelector.matchLabels.role 246 | transforms: 247 | - type: string 248 | string: 249 | fmt: "%s-nodegroup" 250 | - name: iamattachment-cni 251 | base: 252 | apiVersion: iam.aws.crossplane.io/v1beta1 253 | kind: RolePolicyAttachment 254 | spec: 255 | forProvider: 256 | policyArn: arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy 257 | roleNameSelector: 258 | matchControllerRef: true 259 | patches: 260 | - fromFieldPath: spec.id 261 | toFieldPath: metadata.name 262 | transforms: 263 | - type: string 264 | string: 265 | fmt: "%s-cni" 266 | - fromFieldPath: spec.id 267 | toFieldPath: spec.forProvider.roleNameSelector.matchLabels.role 268 | transforms: 269 | - type: string 270 | string: 271 | fmt: "%s-nodegroup" 272 | - name: iamattachment-registry 273 | base: 274 | apiVersion: iam.aws.crossplane.io/v1beta1 275 | kind: RolePolicyAttachment 276 | spec: 277 | forProvider: 278 | policyArn: arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly 279 | roleNameSelector: 280 | matchControllerRef: true 281 | patches: 282 | - fromFieldPath: spec.id 283 | toFieldPath: metadata.name 284 | transforms: 285 | - type: string 286 | string: 287 | fmt: "%s-registry" 288 | - fromFieldPath: spec.id 289 | toFieldPath: spec.forProvider.roleNameSelector.matchLabels.role 290 | transforms: 291 | - type: string 292 | string: 293 | fmt: "%s-nodegroup" 294 | - name: vpc-nodepool 295 | base: 296 | apiVersion: ec2.aws.crossplane.io/v1beta1 297 | kind: VPC 298 | spec: 299 | forProvider: 300 | region: us-east-1 301 | cidrBlock: 10.0.0.0/16 302 | enableDnsSupport: true 303 | patches: 304 | - fromFieldPath: spec.id 305 | toFieldPath: metadata.name 306 | - name: sg-nodepool 307 | base: 308 | apiVersion: ec2.aws.crossplane.io/v1beta1 309 | kind: SecurityGroup 310 | spec: 311 | forProvider: 312 | description: Cluster communication with worker nodes 313 | groupName: devops-catalog 314 | region: us-east-1 315 | vpcIdSelector: 316 | matchControllerRef: true 317 | egress: 318 | - fromPort: 0 319 | toPort: 0 320 | ipProtocol: "-1" 321 | ipRanges: 322 | - cidrIp: "0.0.0.0/0" 323 | patches: 324 | - fromFieldPath: spec.id 325 | toFieldPath: metadata.name 326 | - name: subnet-nodepool-1a 327 | base: 328 | apiVersion: ec2.aws.crossplane.io/v1beta1 329 | kind: Subnet 330 | metadata: 331 | labels: 332 | zone: us-east-1a 333 | access: public 334 | spec: 335 | forProvider: 336 | region: us-east-1 337 | availabilityZone: us-east-1a 338 | cidrBlock: 10.0.0.0/24 339 | vpcIdSelector: 340 | matchControllerRef: true 341 | mapPublicIPOnLaunch: true 342 | tags: 343 | - key: kubernetes.io/role/elb 344 | value: "1" 345 | patches: 346 | - fromFieldPath: spec.id 347 | toFieldPath: metadata.name 348 | transforms: 349 | - type: string 350 | string: 351 | fmt: "%s-1a" 352 | - name: subnet-nodepool-1b 353 | base: 354 | apiVersion: ec2.aws.crossplane.io/v1beta1 355 | kind: Subnet 356 | metadata: 357 | labels: 358 | zone: us-east-1b 359 | access: public 360 | spec: 361 | forProvider: 362 | region: us-east-1 363 | availabilityZone: us-east-1b 364 | cidrBlock: 10.0.1.0/24 365 | vpcIdSelector: 366 | matchControllerRef: true 367 | mapPublicIPOnLaunch: true 368 | tags: 369 | - key: kubernetes.io/role/elb 370 | value: "1" 371 | patches: 372 | - fromFieldPath: spec.id 373 | toFieldPath: metadata.name 374 | transforms: 375 | - type: string 376 | string: 377 | fmt: "%s-1b" 378 | - name: subnet-nodepool-1c 379 | base: 380 | apiVersion: ec2.aws.crossplane.io/v1beta1 381 | kind: Subnet 382 | metadata: 383 | labels: 384 | zone: us-east-1c 385 | access: public 386 | spec: 387 | forProvider: 388 | region: us-east-1 389 | availabilityZone: us-east-1c 390 | cidrBlock: 10.0.2.0/24 391 | vpcIdSelector: 392 | matchControllerRef: true 393 | mapPublicIPOnLaunch: true 394 | tags: 395 | - key: kubernetes.io/role/elb 396 | value: "1" 397 | patches: 398 | - fromFieldPath: spec.id 399 | toFieldPath: metadata.name 400 | transforms: 401 | - type: string 402 | string: 403 | fmt: "%s-1c" 404 | - name: gateway 405 | base: 406 | apiVersion: ec2.aws.crossplane.io/v1beta1 407 | kind: InternetGateway 408 | spec: 409 | forProvider: 410 | region: us-east-1 411 | vpcIdSelector: 412 | matchControllerRef: true 413 | patches: 414 | - fromFieldPath: spec.id 415 | toFieldPath: metadata.name 416 | - name: routetable 417 | base: 418 | apiVersion: ec2.aws.crossplane.io/v1beta1 419 | kind: RouteTable 420 | spec: 421 | forProvider: 422 | region: us-east-1 423 | vpcIdSelector: 424 | matchControllerRef: true 425 | routes: 426 | - destinationCidrBlock: 0.0.0.0/0 427 | gatewayIdSelector: 428 | matchControllerRef: true 429 | associations: 430 | - subnetIdSelector: 431 | matchControllerRef: true 432 | matchLabels: 433 | zone: us-east-1a 434 | access: public 435 | - subnetIdSelector: 436 | matchControllerRef: true 437 | matchLabels: 438 | zone: us-east-1b 439 | access: public 440 | - subnetIdSelector: 441 | matchControllerRef: true 442 | matchLabels: 443 | zone: us-east-1c 444 | access: public 445 | patches: 446 | - fromFieldPath: spec.id 447 | toFieldPath: metadata.name 448 | - name: helm 449 | base: 450 | apiVersion: helm.crossplane.io/v1beta1 451 | kind: ProviderConfig 452 | spec: 453 | credentials: 454 | source: Secret 455 | secretRef: 456 | key: kubeconfig 457 | patches: 458 | - fromFieldPath: spec.id 459 | toFieldPath: metadata.name 460 | - fromFieldPath: spec.writeConnectionSecretToRef.namespace 461 | toFieldPath: spec.credentials.secretRef.namespace 462 | - fromFieldPath: spec.id 463 | toFieldPath: spec.credentials.secretRef.name 464 | transforms: 465 | - type: string 466 | string: 467 | fmt: "%s-cluster" 468 | readinessChecks: 469 | - type: None 470 | - name: crossplane 471 | base: 472 | apiVersion: helm.crossplane.io/v1beta1 473 | kind: Release 474 | spec: 475 | rollbackLimit: 3 476 | forProvider: 477 | namespace: crossplane-system 478 | chart: 479 | name: crossplane 480 | repository: https://charts.crossplane.io/stable 481 | version: "1.5.0" 482 | patches: 483 | - fromFieldPath: spec.id 484 | toFieldPath: metadata.name 485 | transforms: 486 | - type: string 487 | string: 488 | fmt: "%s-crossplane" 489 | - fromFieldPath: spec.id 490 | toFieldPath: spec.providerConfigRef.name 491 | - name: prometheus 492 | base: 493 | apiVersion: helm.crossplane.io/v1beta1 494 | kind: Release 495 | spec: 496 | rollbackLimit: 3 497 | forProvider: 498 | namespace: prometheus 499 | chart: 500 | name: prometheus 501 | repository: https://prometheus-community.github.io/helm-charts 502 | version: "14.9.2" 503 | patches: 504 | - fromFieldPath: spec.id 505 | toFieldPath: metadata.name 506 | transforms: 507 | - type: string 508 | string: 509 | fmt: "%s-prometheus" 510 | - fromFieldPath: spec.id 511 | toFieldPath: spec.providerConfigRef.name 512 | - name: kubernetes 513 | base: 514 | apiVersion: kubernetes.crossplane.io/v1alpha1 515 | kind: ProviderConfig 516 | spec: 517 | credentials: 518 | source: Secret 519 | secretRef: 520 | key: kubeconfig 521 | patches: 522 | - fromFieldPath: spec.id 523 | toFieldPath: metadata.name 524 | - fromFieldPath: spec.writeConnectionSecretToRef.namespace 525 | toFieldPath: spec.credentials.secretRef.namespace 526 | - fromFieldPath: spec.id 527 | toFieldPath: spec.credentials.secretRef.name 528 | transforms: 529 | - type: string 530 | string: 531 | fmt: "%s-cluster" 532 | readinessChecks: 533 | - type: None 534 | - name: ns-prod 535 | base: 536 | apiVersion: kubernetes.crossplane.io/v1alpha1 537 | kind: Object 538 | spec: 539 | forProvider: 540 | manifest: 541 | apiVersion: v1 542 | kind: Namespace 543 | metadata: 544 | name: production 545 | patches: 546 | - fromFieldPath: spec.id 547 | toFieldPath: metadata.name 548 | transforms: 549 | - type: string 550 | string: 551 | fmt: "%s-ns-prod" 552 | - fromFieldPath: spec.id 553 | toFieldPath: spec.providerConfigRef.name 554 | - name: k8s-provider-sa 555 | base: 556 | apiVersion: kubernetes.crossplane.io/v1alpha1 557 | kind: Object 558 | spec: 559 | forProvider: 560 | manifest: 561 | apiVersion: v1 562 | kind: ServiceAccount 563 | metadata: 564 | name: provider-kubernetes 565 | namespace: crossplane-system 566 | patches: 567 | - fromFieldPath: spec.id 568 | toFieldPath: metadata.name 569 | transforms: 570 | - type: string 571 | string: 572 | fmt: "%s-k8s-provider-sa" 573 | - fromFieldPath: spec.id 574 | toFieldPath: spec.providerConfigRef.name 575 | - name: k8s-provider-crd 576 | base: 577 | apiVersion: kubernetes.crossplane.io/v1alpha1 578 | kind: Object 579 | spec: 580 | forProvider: 581 | manifest: 582 | apiVersion: rbac.authorization.k8s.io/v1 583 | kind: ClusterRoleBinding 584 | metadata: 585 | name: provider-kubernetes 586 | subjects: 587 | - kind: ServiceAccount 588 | name: provider-kubernetes 589 | namespace: crossplane-system 590 | roleRef: 591 | kind: ClusterRole 592 | name: cluster-admin 593 | apiGroup: rbac.authorization.k8s.io 594 | patches: 595 | - fromFieldPath: spec.id 596 | toFieldPath: metadata.name 597 | transforms: 598 | - type: string 599 | string: 600 | fmt: "%s-k8s-provider-crb" 601 | - fromFieldPath: spec.id 602 | toFieldPath: spec.providerConfigRef.name 603 | - name: k8s-provider-cc 604 | base: 605 | apiVersion: kubernetes.crossplane.io/v1alpha1 606 | kind: Object 607 | spec: 608 | forProvider: 609 | manifest: 610 | apiVersion: pkg.crossplane.io/v1alpha1 611 | kind: ControllerConfig 612 | metadata: 613 | name: provider-kubernetes 614 | spec: 615 | serviceAccountName: provider-kubernetes 616 | patches: 617 | - fromFieldPath: spec.id 618 | toFieldPath: metadata.name 619 | transforms: 620 | - type: string 621 | string: 622 | fmt: "%s-k8s-provider-cc" 623 | - fromFieldPath: spec.id 624 | toFieldPath: spec.providerConfigRef.name 625 | - name: k8s-provider 626 | base: 627 | apiVersion: kubernetes.crossplane.io/v1alpha1 628 | kind: Object 629 | spec: 630 | forProvider: 631 | manifest: 632 | apiVersion: pkg.crossplane.io/v1 633 | kind: Provider 634 | metadata: 635 | name: provider-kubernetes 636 | spec: 637 | package: crossplane/provider-kubernetes:main 638 | controllerConfigRef: 639 | name: provider-kubernetes 640 | patches: 641 | - fromFieldPath: spec.id 642 | toFieldPath: metadata.name 643 | transforms: 644 | - type: string 645 | string: 646 | fmt: "%s-k8s-provider" 647 | - fromFieldPath: spec.id 648 | toFieldPath: spec.providerConfigRef.name 649 | 650 | --------------------------------------------------------------------------------