pulumi / pulumi-kubernetes-operator

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

Support for Structured Configuration #513

Closed EronWright closed 8 months ago

EronWright commented 8 months ago

Hello!

Issue details

Add support for structured configuration to be passed to the Pulumi program. The use cases are:

  1. Passing an object value to the program, e.g. to be retrieved at runtime with RequireObject.
  2. Setting the value of a specific path into a merged configuration.

The value would assumedly come from any of the supported sources, mainly:

Ideally this feature would be orthogonal to whether or not the value is Pulumi secret.

There may be need for a new configuration block to allow for non-secret structured configuration. Note that secretsRef defines Pulumi secrets from a secret or from a literal value, while non-secrets are simply typed as map[string]string.

Note that the Automation API recently added support for structured configuration: https://github.com/pulumi/pulumi/pull/12265

Examples

Some examples for illustration purposes.

These examples assume the following program:

interface Data {
    active: boolean;
    nums: number[];
}

let config = new pulumi.Config();
let data = config.requireObject<Data>("mydata");
console.log(`Active: ${data.active}`);

And intend to generate the following stack configuration:

# Generated: Pulumi.dev.config
config:
  proj:mydata:
    active: true
    nums:
    - 1
    - 2
    - 3

Using a YAML value from a Kubernetes Secret as a Pulumi secret:

apiVersion: v1
kind: Secret
metadata:
  name: example-secret
type: Opaque
stringData:
  data.yaml: |
    active: true
    nums:
    - 10
    - 20
    - 30
---
apiVersion: pulumi.com/v1
kind: Stack
metadata:
  name: example-1
spec:
  stack: example/proj/dev
  config:
    aws:region: us-east-2
  secretsRef:
    mydata:
      type: secret
      secret:
        name: example-secret
        key: data.yaml
        type: object
  ...

Using an inline YAML value as a Pulumi secret:

apiVersion: pulumi.com/v1
kind: Stack
metadata:
  name: example-1
spec:
  stack: example/proj/dev
  config:
    aws:region: us-east-2
  secretsRef:
    mydata:
      type: literal
      literal:
        jsonValue:
          active: true
          nums:
          - 10
          - 20
          - 30
  ...

Using inline YAML as a non-secret (via a hypothetical config2 block):

apiVersion: pulumi.com/v1
kind: Stack
metadata:
  name: example-1
spec:
  stack: example/proj/dev
  config2:
    aws:region:
      type: string
      value: us-east-2
    proj:mydata:
      type: object
      value:
        active: true
        nums:
        - 10
        - 20
        - 30
  ...

Open Questions

  1. Config values are currently typed as string as opposed to apiextensionsv1.JSON. If we were to change the API to use JSON, then the values would be interpreted as JSON values (e.g. true would become a bool). Is that an acceptable (breaking) change? Or should a jsonValue field be introduced? Or should literals be string-encoded? Note that Program.spec.configuration.default is a JSON value (not encoded).
  2. Should the API types use json.RawMessage rather than apiextensionsv1.JSON? See Grafana and Tanzu for examples.
EronWright commented 8 months ago

Closing as a dup of https://github.com/pulumi/pulumi-kubernetes-operator/issues/258

pulumi-bot commented 8 months ago

Cannot close issue:

Please fix these problems and try again.