mumoshu / aws-secret-operator

A Kubernetes operator that automatically creates and updates Kubernetes secrets according to what are stored in AWS Secrets Manager.
Apache License 2.0
334 stars 42 forks source link

How to add multiple secrets #22

Open dnarwani opened 4 years ago

dnarwani commented 4 years ago

I have a secret called

apiVersion: mumoshu.github.io/v1alpha1 kind: AWSSecret metadata: name: db-secrets namespace: authentication spec: stringDataFrom: secretsManagerSecretRef: secretId: mysecret versionId: ee113603-3254-478a-bb27-40027ae4ff60

I want to be to add multiple entries in 1 secret, is this possible?

ghostsquad commented 4 years ago

is this possible? I'd also like to know.

mumoshu commented 4 years ago

Hi! Unfortunately, it isn't possible today. Can we just extend the spec to accept two or more secretsManagerSecretRefs and merge them? On duplicate key, the latter and newer value for the key will win over the old one

Also I'm curious - what's the expected use-case of this?

osterman commented 4 years ago

what's the expected use-case of this?

Avoid polluting ASM with too many key/value pairs, and be able to atomic updates to a set of secrets that are related and should be versioned together.

See an example here: https://docs.aws.amazon.com/secretsmanager/latest/userguide/tutorials_basic.html

They provide an example like this one which has a username and password for a service:

$ aws secretsmanager get-secret-value --secret-id tutorials/MyFirstTutorialSecret --version-stage AWSCURRENT
{
    "ARN": "arn:aws:secretsmanager:region:123456789012:secret:tutorials/MyFirstTutorialSecret-jiObOV",
    "Name": "tutorials/MyFirstTutorialSecret",
    "VersionId": "EXAMPLE1-90ab-cdef-fedc-ba987EXAMPLE",
    "SecretString": "{\"username\":\"myserviceusername\",\"password\":\"MyVerySecureP@ssw0rd!\"}",
    "VersionStages": [
        "AWSCURRENT"
    ],
    "CreatedDate": 1522680764.668
}

So I think a similar expectation where we could serialize perhaps the secret as JSON when we write it to ASM. Then when the operator writes the secret, it becomes something like this (basing it off the example here):

{
  "kind": "Secret",
  "apiVersion": "v1",
  "metadata": {
    "name": "example",
    "namespace": "default",
    "selfLink": "/api/v1/namespaces/default/secrets/test",
    "uid": "82ef45ee-4fdd-11e8-87bf-00e092001ba4",
    "resourceVersion": "25758",
    "creationTimestamp": "2018-05-04T20:55:43Z"
  },
  "data": {"username":"myserviceusername", "password":"MyVerySecureP@ssw0rd!"}",
  "type": "Opaque"
}

maybe we would define the AWSSecret like this with a new deserialize flag:

apiVersion: mumoshu.github.io/v1alpha1
kind: AWSSecret
metadata:
  name: example
spec:
  stringDataFrom:
    secretsManagerSecretRef:
      secretId: prod/mysecret
      deserialize: true
      versionId: c43e66cb-d0fe-44c5-9b7e-d450441a04be
osterman commented 4 years ago

Actually, I think in your example, you already show how this is possible:

$ aws secretsmanager put-secret-value\
    --secret-id prod/mysecret \
    --secret-string '{"foo":"bar"}'`

So maybe it already works? =) @nuru can you try?

e.g.

$ aws secretsmanager put-secret-value\
    --secret-id prod/mysecret \
    --secret-string '{"username":"keycloak", "password":"supersecret"}'`

(I think this is different from what @dnarwani is asking, but this works for our use-case)

casey-robertson commented 4 years ago

Just started investigating secretsmanager to move away from a sops-based workflow. Agree with @osterman that the above should just work. I am building secrets with Pulumi but I add this an example value:

const fruit = JSON.stringify({
  fruit: "Apple",
  size: "Medium",
  color: "Red",
});

This results in being able to do the following which aligns with how our applications currently use secrets. Right now they are encrypted in the repo (appsettings.json). Upon deploy, sops decrypts the secrets in place - that folder is then mounted as a Secrets volume in the pod.

aws secretsmanager get-secret-value --secret-id casey-config | jq -r .SecretString | jq
{
  "fruit": "Apple",
  "size": "Medium",
  "color": "Red"
}

Glad I stumbled across this because my first thought was to:

  1. Add new step to CI/CD to take decrypted secrets and push them to SSM. Or push them encrypted and work out a plan to pull them all back globally into a single 'master' repo. Still trying to understand that concept.
  2. Add new step to CI/CD that goes and gets the secrets from SM and drops them in the same folder/directory
  3. Deprecate sops step.

End result is same file mounted as a secret in Kubernetes - however with the risks/caveats outlined in the readme about the CI/CD system having decrypted secrets etc. I'll still probably work on step 1 to do initial secret population.

sh240293 commented 2 years ago

Hey, can any one suggest to use secrets from parameter store using this method. I have used this https://github.com/toVersus/aws-ssm-operator which points as a ref to this repo. But here i am not able to get secrets more than 10, I have used path type and settings working fine, but there is a hard limit of 10 somewhere defined i think , Please help me if anyone knows how we can increase.

mumoshu commented 2 years ago

@sh240293 This is what it does and there's no hard limit of 10.

https://github.com/mumoshu/aws-secret-operator/blob/564875e31ec98992f83252f0d4896c77b3f79343/controllers/awssecret_controller.go#L57-L115

Also, this issue was about trying to create a single K8s secret from multiple secretsmanager secrets using the key hierarchy, which isn't relevant with your goal as I think,

sh240293 commented 2 years ago

Hey @mumoshu thanks for the reply, I have configured an operator that works with parameter store on basis of path and it will sync all variables defined at that common path, however i gone through deep into troubleshoot i got this error message

"E0414 06:29:07.599684 1 reflector.go:134] sigs.k8s.io/controller-runtime/pkg/cache/internal/informers_map.go:126: Failed to list *v1alpha1.ParameterStore: v1alpha1.ParameterStoreList.Items: []v1alpha1.ParameterStore: v1alpha1.ParameterStore.Spec: v1alpha1.ParameterStoreSpec.ValueFrom: v1alpha1.ValueFrom.ParameterStoreRef: v1alpha1.ParameterStoreRef.Path: ReadString: expects " or n, but found [, error found in #10 byte of ...|:{"path":["/farmstoc|..., bigger context ...|"spec":{"valueFrom":{"parameterStoreRef":{"path":["/farmstock-backend/dev/"]}}}}],"kind":"ParameterS|..."

I have no idea on the coding part, but if you can suggest how i can fix that would be really helpful to me. That https://github.com/toVersus/aws-ssm-operator unfortunately this github owner is not responding.

mumoshu commented 2 years ago

@sh240293 Hey. Your error seems to be coming from https://github.com/toVersus/aws-ssm-operator, not aws-secret-operator.