pulumi / pulumi-kubernetes-operator

A Kubernetes Operator that automates the deployment of Pulumi Stacks
Apache License 2.0
218 stars 55 forks source link

Multi-tenancy considerations #501

Open pdf opened 11 months ago

pdf commented 11 months ago

Hello!

Issue details

The current CRDs do not provide a method of exposing Pulumi programs/stacks to unprivileged users/processes.

An example scenario of where this is problematic:

We wish to be able to allow unprivileged users to create/destroy S3 buckets with a templated name, and obtain bucket-specific credentials to use within their deployments.

The IAM privileges required by the operator for these operations are quite significant, but given the design of the Stack/Program CRDs there is no way to limit the operations that a user might perform if we allow them to write these resources directly.

Proposed solution

This is not a formal proposal, but may serve as a starting point for discussion.

One possible path to providing the capability to expose specific stacks/programs would be to introduce a CRD-generating meta resource definition, consuming that CRD that might look something like this:

---
apiVersion: pulumi.com/v1
kind: StackResource
metadata:
  name: s3bucket
spec:
  group: my.group.org
  names:
    kind: s3bucket
  versions:
    - name: v1
      config:
        region:
          type: String
      template:
        metadata:
          name: ${claim.metadata.namespace}-${claim.metadata.name}
          namespace: operator-namespace
          labels: ${claim.metadata.labels}
        spec:
          stack: <YOUR ORG>/s3bucket/${claim.metadata.namespace}-${claim.metadata.name}
          programRef:
            name: bucketoprivs
          destroyOnFinalize: true
          config:
            aws:region: ${claim.spec.config.region}
            claim:name: ${claim.metadata.name}
            other:key: static-value

This cribs some properties from regular CRD spec, with the idea that upon creating such a CR the operator would generate a CRD based on the provided properties. The template field of the version would be used by the operator to create a Stack CR in the operator NS whenever a CR for the generated CRD is created (and bound to the lifecycle of the user CR), which should allow the existing operator logic to continue operating on stacks without modification. A user would consume the generated CRD like so:

---
apiVersion: my.group.org/v1
kind: s3bucket
metadata:
  name: stackname
spec:
  config:
    region: us-east-1

By generating this intermediate CRD we can allow users to consume Stacks/Programs without exposing the full power/privileges of the operator, and control access using standard k8s RBAC.

I'm hand-waving away a lot of details here, but can try to allocate some more design time if this is an approach that seems sensible.

cleverguy25 commented 1 month ago

Added to epic https://github.com/pulumi/pulumi-kubernetes-operator/issues/586