xlab-si / xopera-opera

xOpera orchestrator compliant with TOSCA YAML v1.3 in the making
https://xlab-si.github.io/xopera-docs/
Apache License 2.0
35 stars 14 forks source link

Enable better configuration of orchestration process #243

Open anzoman opened 2 years ago

anzoman commented 2 years ago

Description

Our opera TOSCA orchestrator has a lot of different orchestration actions such as deploy and undeploy. These are currently configured to run the on the localhost by default and when the user wants to connect to remote machine (via SSH protocol) and run deployment there, he can create the workstation node (derived from tosca.nodes.Compute), set his remote VM IP within public_address TOSCA attribute and use different environment variables to set the appropriate remote SSH user (OPERA_SSH_USER=ubuntu), SSH private key file (OPERA_SSH_IDENTITY_FILE=~/.ssh/secret.key) or disable host key checking (OPERA_SSH_HOST_KEY_CHECKING=false).

Having environment variables is an option but the problem is when the user wants to connect to multiple machines and run different parts of deployment within different environments. It is possible to configure that within the Ansible playbooks (see this) but our future executors (like bash and python) will not have that option. So, I'm proposing that we think about implementing the ability to configure the orchestration process via configuration file (in TOML, YAML, JSON, INI, XML or whatever format) that could include necessary host definitions, paths to SSH keys, mappings between instances and hosts and other configurations. This functionality could be done similar to Ansible inventory, where users define multiple managed hosts for their infrastructure.

This config file could be passed to the orchestrator when deploying (similar to orchestration inputs we could create a flag -c/--config), for instance with opera deploy --config config.yaml service.yaml and the configuration could be copied to xOpera storage folder (the path could be .opera/config).

Steps

TBD if we decide to even do that. It is important that we define which params will be in the config file and how will we define them.

Current behaviour

Apart from default behaviour, the configuration is done partially through TOSCA, executors (Ansible) and environment variables.

Expected results

To be able to define the configuration of orchestration process using config file in the specified format.

abitrolly commented 2 years ago

A timely issue. I was about to raise the same question, so thanks for the outrunning me with the issue. ) I would only narrow the title to "managing access credentials". Right now there are three options.

  1. Environment variables (more or less secure, but not completely)
  2. Input variables that are saved in a state (insecure if not encrypted)
  3. Playbooks (totally insecure)

So environment variables would be fine, but as you said it is impossible to supply different credentials for different hosts just using them, and my opinion is that it should be described in TOSCA standard, to stop reinventing the wheel.

anzoman commented 2 years ago

@cankarm, @sstanovnik, @alexmaslenn, @dradx what do you think about this feature for the future?

sstanovnik commented 2 years ago

I think everything should be done through TOSCA inputs, but the problem is that we'd need to pass some variables to the executor. We do have to do that with the Ansible inventory now anyway, don't we? I imagine it would follow the same principles. Secrets are an issue because of logging though. Is there a standard way of specifying secrets anywhere? Or can we add an annotation somewhere that says to opera not to log or write those values to disk?

alexmaslenn commented 2 years ago

I agree that we should not introduce another set of configuration parameters for orchestration. TOSCA inputs should be enough for handling the issues mentioned above, given that playbooks and TOSCA node types are implemented properly. Current issue with inputs is security, as they are stored in plain text. But this concern is addressed in #143

dradX commented 2 years ago

I agree with @alexmaslenn and @sstanovnik - TOSCA actually supports all this kind of settings through map types (3.3.5.2.2 Map declaration using a complex type) and inputs. Using another way to setup parameters instead of inputs would be taking a route out of the standard TOSCA, since then the user would have to consider "yet another config" to set up and take care of. In my opinion, this is not specifically a TOSCA (standard) problem as @abitrolly suggests but rather an opera implementation problem and consequentially "setting up a guideline" or typical usage (example) would be the best way to address this.
To conclude my suggestion would be using inputs and setting up an example of host:key map usage showing how this can be done. Regarding inputs and secrets my opinion stays the same as before (see #143 and beyond) - since opera has to store the inputs/state (one way or another), which may/usually contain sensitive information we should enable the user to protect this state with encryption.

anzoman commented 2 years ago

Thanks for all your proposals, I agree that having config file does not resemble the standard way with TOSCA - this config file would be more appropriate if we (ever) decide to support other orchestration standards/specifications. So, configuring the orchestration through TOSCA inputs via predefined complex data type (as @dradX suggested - section 3.3.5.2.2: Map declaration using a complex type) seems to be just fine. We would just need to try this first with our env vars and encapsulate them into complex type (it could be called Configuration) like this:

opera.datatypes.Configuration:
  derived_from: tosca.datatypes.Root
  properties: 
    ssh_user:
      type: string
    ssh_private_key_file:
      type: string
    ssh_host_key_checking:
      type: boolean

There is also a possibility that we define one major configuration type for orchestrator (what all executors have in common) and other types that have properties specific for each executor (e.g., Ansible, Python, bash, ...). After that we can assemble which other properties and functionalities do we need also to pass to executors (e.g., multiple ssh users and keys, etc.) and add them to our configuration data type. An important part is also that we document all the configuration settings.

anzoman commented 2 years ago

Also wanted to add that - if we use inputs for configuration and define some new type for that with reserved keynames, we also have to take into account that this might not be pure TOSCA anymore (do we need to define our own tosca_definitions_version then?) and we need to warn the user if he will ever define the same structure within his templates (we do this already with ToscaDeviationError when using notification keyname for opera notify)