propellor-5.18: property-based host configuration management in haskell

Safe Haskell | None
Language | Haskell2010

Propellor.Property.Conductor

Description

This module adds conductors to propellor. A conductor is a Host that is responsible for running propellor on other hosts

This eliminates the need to manually run propellor --spin to update the conducted hosts, and can be used to orchestrate updates to hosts.

The conductor needs to be able to ssh to the hosts it conducts, and run propellor, as root. To this end, the `knownHost` property is automatically added to the conductor, so it knows the host keys of the relevant hosts. Also, each conducted host is configured to let its conductor ssh in as root, by automatically adding the `authorizedKeysFrom` property.

It's left up to you to use `userKeys` to configure the ssh keys for the root user on conductor hosts, and to use `hostKeys` to configure the host keys for the conducted hosts.

For example, if you have some webservers and a dnsserver, and want the master host to conduct all of them:

     import Propellor
     import Propellor.Property.Conductor
     import qualified Propellor.Property.Ssh as Ssh
     import qualified Propellor.Property.Cron as Cron

     main = defaultMain (orchestrate hosts)

     hosts =
     	[ master
    	, dnsserver
    	] ++ webservers

     dnsserver = host "dns.example.com"
    	& Ssh.hostKeys hostContext [(SshEd25519, "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIB3BJ2GqZiTR2LEoDXyYFgh/BduWefjdKXAsAtzS9zeI")]
    	& ...

     webservers =
        [ host "www1.example.com"
    		& Ssh.hostKeys hostContext [(SshEd25519, "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICfFntnesZcYz2B2T41ay45igfckXRSh5uVffkuCQkLv")]
    		& ...
    	, ...
    	]

     master = host "master.example.com"
    	& Ssh.userKeys (User "root") [(SshEd25519, "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFWD0Hau5FDLeNrDHKilNMKm9c68R3WD+NJOp2jPWvJV")]
    	& conducts webservers
    		`before` conducts dnsserver
    	& Cron.runPropellor

Notice that, in the above example, the the webservers are conducted first. Only once the webservers have successfully been set up is the dnsserver updated. This way, when adding a new web server, the dns won't list it until it's ready.

There can be multiple conductors, and conductors can conduct other conductors if you need such a hierarchy. (Loops in the hierarchy, such as a host conducting itself, are detected and automatically broken.)

While it's allowed for a single host to be conducted by multiple conductors, the results can be discordent. Since only one propellor process can be run on a host at a time, one of the conductors will fail to communicate with it.

Note that a conductor can see all PrivData of the hosts it conducts.

Synopsis

- orchestrate :: [Host] -> [Host]
- class Conductable c where
  - conducts :: c -> RevertableProperty (HasInfo + UnixLike) (HasInfo + UnixLike)

# Documentation

orchestrate :: [Host] -> [Host] Source #

Pass this a list of all your hosts; it will finish setting up orchestration as configured by the `conducts` properties you add to hosts.

    main = defaultMain $ orchestrate hosts

class Conductable c where Source #

Class of things that can be conducted.

There are instances for single hosts, and for lists of hosts. With a list, each listed host will be conducted in turn. Failure to conduct one host does not prevent conducting subsequent hosts in the list, but will be propagated as an overall failure of the property.

Methods

conducts :: c -> RevertableProperty (HasInfo + UnixLike) (HasInfo + UnixLike) Source #

#### Instances

Instances details

Conductable Host Source # |
Instance details Defined in Propellor.Property.Conductor Methods conducts :: Host -> RevertableProperty (HasInfo + UnixLike) (HasInfo + UnixLike) Source #
Conductable [Host] Source # |
Instance details Defined in Propellor.Property.Conductor Methods conducts :: [Host] -> RevertableProperty (HasInfo + UnixLike) (HasInfo + UnixLike) Source #