NixOS / nixops

NixOps is a tool for deploying to NixOS machines in a network or cloud.
https://nixos.org/nixops
GNU Lesser General Public License v3.0
1.83k stars 363 forks source link

DigitalOcean multi-server deployment fails due to SSH key duplication #819

Open ghost opened 6 years ago

ghost commented 6 years ago

Formalizing https://github.com/NixOS/nixops/pull/562#issuecomment-313917049

To reproduce this, use something along the lines of

{
  resources.sshKeyPairs.ssh-key = {};

  machine = { config, pkgs, ... }: {
    services.nginx.enable = true;
    services.openssh.enable = true;

    deployment.targetEnv = "digitalOcean";
    deployment.digitalOcean.region = "tor1";
    deployment.digitalOcean.size = "512mb";
  };

  second-machine = { config, pkgs, ... }: {
    services.redis.enable = true;
    services.openssh.enable = true;

    deployment.targetEnv = "digitalOcean";
    deployment.digitalOcean.region = "tor1";
    deployment.digitalOcean.size = "512mb";
  };
}

You should get an error like

...
Warning: Permanently added 'DROPLET_ADDRESS' (ED25519) to the list of known hosts.
machine.......> setting state version to 16.09
error: SSH Key is already in use on your account

Currently working on a pull request to fix this (as well as update the nixos-infect script to 17.09)

It works somewhere along the lines of

key = digitalocean.SSHKey(token=self.get_auth_token())
key.load_by_pub_key(ssh_key.public_key)

if key.id == "": # if key is not found / isn't loaded
    key = digitalocean.SSHKey(token=self.get_auth_token(), name='NixOps SSH Key ' + self.name, public_key=ssh_key.public_key)
    key.create()

This simply loads the key if it already exists, which prevents key duplication (and ultimately, an error). If someone could provide some insight as to how I can create those keys or do that check before the creation of the droplets (because it looks like I'm forming some kind of race condition where both servers are created at the same time and therefore they don't detect each other's keys)

Hoverbear commented 6 years ago

Thanks for reporting this @mhsjlw =D

Did you end up resolving it?

ghost commented 6 years ago

Well, there is a crappy hack to get around this if you delete the key right after it creates the droplet (in the DigtalOcean panel)

But, no, it hasn't been formally fixed yet. The reason being, I'm not happy with my solution of just loading the key if it already exists (by the way, that doesn't even work. Not sure if I'm misusing the API or if it's just flat-out broken). What should really happen is key management should be implemented properly-- however I'm yet to do that

ghost commented 6 years ago

To the maintainers: this has been dead in the water, I am willing to work on it, but I will need guidance. As well, https://github.com/NixOS/nixops/pull/820 needs to be 'resolved', as in, we need a better way to update the nixops-infect script, or just have someone to be responsible for updating it.

ghost commented 6 years ago

I haven't tried, yet, but would an acceptable solution be to use DigitalOcean API to destroy the key as soon as the droplet is created? Is there any reason why NixOps generated public keys need to be accessible from DO interface?

smalltalker55 commented 5 years ago

I am new to nixops. I have been playing around with it on VirtualBox and now am ready to try it on DigitalOcean. Does this issue imply that nixops isn't really working on DigitalOcean?

ghost commented 5 years ago

I have not used NixOps since I had posted this issue, but NixOps multi-node deployments will not work correctly on DigitalOcean if this issue still applies

jlmeeker commented 4 years ago

bump... looking at using NixOps on DO and this is a real show-stopper... Still no progress after 2 years?