Operator-sdk: Support for ansible-vault

Created on 24 Nov 2019  ยท  6Comments  ยท  Source: operator-framework/operator-sdk

Feature Request

Is your feature request related to a problem? Please describe.
I have an issue when I need to store sensitive data within the confines of the Ansible operator. At present, there isn't a means to do so using native Ansible features like ansible-vault.

Describe the solution you'd like
We use ansible-vault to encrypt secrets within the confines of an ansible playbook. This is simply done using the ansible-vault command, pasting in a string to encrypt, and it returns a hash. In order to access the secrets, the --ask-vault-pass option must be supplied to the ansible-playbook command. A prompt is given asking for the vault password, and the password used to create it is used to reveal/decrypt the value.

There's also an option to have a file on the ansible host that contains the password, and this can be fed into the ansible-playbook command in lieu of the ask-vault-pass option.

With the current operator, there's not way, as far as I know, to have ansible run with an option to read a password file, or otherwise. Even so, some mechanism to store the password on the image securely is needed. One option perhaps would be to store the vault password as a k8s secret and looking it up with the ansible k8s module to create the password file, or build a way within the operator binary to look up the k8s secret.

One drawback with this approach is getting the vault password created in the first place. Maybe something like bitnami-labs/sealed-secrets can be used here. Overall perhaps use of sealed secrets addresses some of these challenges, however having a one-stop-shop of native ansible functionality within the confines of the operator makes things a bit more fluid.

My current use case is around storing usernames and passwords in a configuration file for an application, specifically Jetty. The passwords differ across our data center environments, so having the power of group_vars or the like (without having to rely on an inventory) within ansible could be useful within an operator use case. Therefore, this config file needs to be an Ansible template. "The like" would be doing something like this to get namespace specific values, for example, our namespaces may be named solr-dev, solr-tst, solr-prd:

โ””โ”€โ”€ roles
    โ””โ”€โ”€ solr.provisioning
        โ”œโ”€โ”€ defaults
        โ”‚   โ””โ”€โ”€ main.yml
        โ”œโ”€โ”€ meta
        โ”‚   โ””โ”€โ”€ main.yml
        โ”œโ”€โ”€ tasks
        โ”‚   โ””โ”€โ”€ main.yml
        โ”œโ”€โ”€ templates
        โ”‚   โ”œโ”€โ”€ solr.yaml.j2
        โ”‚   โ””โ”€โ”€ zookeeper.yaml.j2
        โ””โ”€โ”€ vars
            โ”œโ”€โ”€ main.yml
            โ””โ”€โ”€ solr-dev.yml
- name: Include environment specific jetty variables
  include_vars: "{{ namespace }}.yml

Now, with all of that said, one of the challenges in my environment is the k8s admin not allowing a service account to create secrets. If I could do that, then I could just set a bunch of facts and use those as vars to supply the credentials to a k8s secret that's simply stringData. Our service accounts, at present, are allowed to perform verbs against any CRDs we've created within the platform. Native CRs are more of less off limits since our service accounts are cluster scoped (service account lives in the namespace of the operator and our operators are cluster scoped).
Regardless, having the ability to use native ansible-vault as opposed to having to rely on k8s secrets (or in some cases in conjunction with k8s secrets) may make things a bit more flexible.

help wanted kinfeature languagansible lifecyclfrozen

All 6 comments

Issues go stale after 90d of inactivity.

Mark the issue as fresh by commenting /remove-lifecycle stale.
Stale issues rot after an additional 30d of inactivity and eventually close.
Exclude this issue from closing by commenting /lifecycle frozen.

If this issue is safe to close now please do so with /close.

/lifecycle stale

/remove-lifecycle stale

cc: @fabianvf

/lifecycle frozen

@fabianvf is willing to help anyone who wants to implement this.

@fabianvf I've never written a single piece of go. I suppose that would be a prerequisite towards helping implement this?

@ktreese it wouldn't hurt, though if you're familiar enough with other programming languages I don't think it would be too hard. I was thinking of making this a more general feature by adding a command line flag to the operator-sdk exec-entrypoint and run --local subcommands for Ansible-based Operators that allowed a user to specify arbitrary CLI arguments that we pass through to ansible-runner. That would mostly just involve:

  1. Adding the flag to the Ansible flag set here: https://github.com/operator-framework/operator-sdk/blob/master/pkg/ansible/flags/flag.go#L40 ,
  2. Updating the Run function to make use of that flag https://github.com/operator-framework/operator-sdk/blob/master/pkg/ansible/run.go#L68
  3. The above step would likely involve adding a field to store the flags to the Runner struct: https://github.com/operator-framework/operator-sdk/blob/master/pkg/ansible/runner/runner.go#L146
  4. Making the cmdFunc interface and the methods that implement it accept and use the additional flag: https://github.com/operator-framework/operator-sdk/blob/master/pkg/ansible/runner/runner.go#L71-L99

And then of course testing/etc. If you did decide to take a stab at it I'd be happy to help, I'm fabianvf on the Kubernetes Slack and freenode.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

magescher picture magescher  ยท  3Comments

lsalazar1 picture lsalazar1  ยท  4Comments

TristanCacqueray picture TristanCacqueray  ยท  5Comments

camilamacedo86 picture camilamacedo86  ยท  4Comments

linuxbsdfreak picture linuxbsdfreak  ยท  4Comments