nais / naisd

nais deployment daemon
https://nais.io
MIT License
27 stars 10 forks source link

Option to map environment variables to other names #66

Closed davidsteinsland closed 6 years ago

davidsteinsland commented 6 years ago

What: Ability to map Fasit properties to custom environment variables How: By specifying a map in nais.yaml:

propertyMap:
  - map: abac.pdp.endpoint.url
    to: ABAC_URL
  - map: srvfoo_username
    to: ABAC_USERNAME

Why: Many Fasit resources are shared among many applications, and you cannot control the naming. If the application expects another property name, we have to do the mapping in the application (runtime).

A typical example is a Spring application which can have it's database configured automatically by providing at least the property spring.datasource.url (or SPRING_DATASOURCE_URL env var). If the database property is mapped in nais.yaml, no more configuration will be needed:

propertyMap:
  - map: mydb_url
     to: SPRING_DATASOURCE_URL
  - map: mydb_username
     to: SPRING_DATASOURCE_USERNAME
gtcno commented 6 years ago

Can we just add a field to the list of used fasit resources: alias: mydb mapTo: whatever resourceType: datasource

I can't see any other usecases except fasit lookup?

davidsteinsland commented 6 years ago

A fasit resource can yield multiple properties, so the mapping would have to be explicit.

jhrv commented 6 years ago

we have this functionality in the old platform as well, but there the mapping only applies to the alias part of the name. E.g.

<datasource alias="gnalias" mapToProperty="mapped" />

would result in the variables mapped.url, mapped.username and mapped.password.

Is this enough to solve your use-case, or do you need control over the whole variable name? I agree with @gtcno that we should try to tie the mapping as close to the resource declaration as possible.

davidsteinsland commented 6 years ago

Not critical, but this would not support applicationProperties. How does this handle conflicts/duplicate names?

Example:

fasitResources: # resources fetched from Fasit
  used:
  - alias: srvapp
    mapToProperty: abac
    resourceType: credential
  - alias: abac.pdp.endpoint
    mapToProperty: abac
    resourceType: restservice

Here we're mapping two resources to abac, because we want the username and password properties of srvapp and the url property of abac.pdp.endpoint to map to ABAC_USERNAME, ABAC_PASSWORD and ABAC_URL. However, it's not all too clear which properties may be set, and we will have to look-up the definition of both credential and restservice to know whether or not there's a collision in property names.


Can the mapping be done like this:

fasitResources: 
  used:
  - alias: srvapp
    propertyMap:
        - username: ABAC_USERNAME
        - password: ABAC_PASSWORD
    resourceType: credential
  - alias: abac.pdp.endpoint
    propertyMap:
        - url: ABAC_URL
    resourceType: restservice

This would then also work for applicationProperties (if needed).

jhrv commented 6 years ago

You're right, it would not work for application properties. However, in a application properties resource you have full control over what the variable name is, so I don't think you need it here.

With regards to having to look up the definition what variables are exposed from a given resource, you also have to do that if you are to explicitly map them. Otherwise I think the last suggestion is a good one, but only if you need to have control over the full variable name. Else we can simplify this to something like @gtcno suggested

davidsteinsland commented 6 years ago

I'd like to have full control over the naming, or non at all. For example, in Spring the LDAP can be auto-configured using:

spring.ldap.base
spring.ldap.urls
spring.ldap.username
spring.ldap.password

If we were to map the Fasit ldap property to SPRING_LDAP, we would get:

SPRING_LDAP_USER_BASEDN
SPRING_LDAP_SERVICEUSER_BASEDN
SPRING_LDAP_DOMAIN
SPRING_LDAP_BASEDN
SPRING_LDAP_URL
SPRING_LDAP_USERNAME
SPRING_LDAP_PASSWORD

As we can see, there's s mismatch for the SPRING_LDAP_URL and SPRING_LDAP_BASEDN env vars, as they should be SPRING_LDAP_URLS and SPRING_LDAP_BASE.

Perhaps we could vote on it?

gtcno commented 6 years ago

If required then a solution where you limit the mapping to fasit resources gets my vote. So +1 to your last suggestion.

jhrv commented 6 years ago

I would say that the example you provided justifies the mapping implementation you suggested 👍