basecamp / kamal

Deploy web apps anywhere.
https://kamal-deploy.org
MIT License
10.6k stars 407 forks source link

Host specific env with tags #789

Closed djmb closed 4 months ago

djmb commented 5 months ago

Allow hosts to be tagged so we can have host specific env variables.

We might want host specific env variables for things like datacenter specific tags or testing GC settings on a specific host.

Right now you either need to set up a separate role, or have the app be host aware.

Now you can define tag env variables and assign those to hosts.

For example:

servers:
  - 1.1.1.1
  - 1.1.1.2: tag1
  - 1.1.1.2: tag2
  - 1.1.1.3: [ tag1, tag2 ]
env_tags:
  tag1:
    ENV1: value1
  tag2:
    ENV2: value2

The tag env supports the full env format, allowing you to set secret and clear values.

dhh commented 4 months ago

This is great, but do we have anything evns we want to apply to these tags? Otherwise it feels like we're nested one level too much. But it's one of those things that if you could imagine anything else, you'd really want the nesting. Maybe just the secret split is enough to warrant?

djmb commented 4 months ago

I suppose you might want tag specific volumes? I'm unconvinced, but having the env key does allow us to handle anything that does show up.

Either way I think the secret/clear split does warrant the env key anyway for clarity. Though I also think tag specific secrets would be rare.

servers:
  - 1.1.1.1
  - 1.1.1.2: tag1
  - 1.1.1.2: tag2
  - 1.1.1.3: [ tag1, tag2 ]
tags:
  tag1:
    clear:
      ENV1: value1
    secret:
      - DB_PASSWORD
  tag2:
    clear:
      ENV1: value1
    secret:
      - REDIS_PASSWORD

vs

servers:
  - 1.1.1.1
  - 1.1.1.2: tag1
  - 1.1.1.2: tag2
  - 1.1.1.3: [ tag1, tag2 ]
tags:
  tag1:
    env: 
      clear:
        ENV1: value1
      secret:
        - DB_PASSWORD
  tag2:
    env:
      clear:
        ENV1: value1
      secret:
        - REDIS_PASSWORD
dhh commented 4 months ago

Let's change this from:

env:
  clear:
    TEST: "root"
    EXPERIMENT: "disabled"
env_tags:
  site1:
    SITE: site1
  site2:
    SITE: site2
  experimental:
    env:
      EXPERIMENT: "enabled"

to:

env:
  clear:
    TEST: "root"
    EXPERIMENT: "disabled"
  tags:
    site1:
      SITE: site1
    site2:
      clear:
        SITE: site2
      secret:
        - SOMETHING_SECRET