Skip to content

surminus/viaduct

Repository files navigation

Viaduct CI Go Reference

A configuration management framework written in Go.

The framework allows you to write configuration in plain Go, which you would then compile and distribute as a binary to the target machines.

This means that you don't need to bootstrap an instance with configuration files or a runtime environment (eg "install chef"): simply download the binary, and run it!

I'm using Viaduct to set up my personal development environment at surminus/myduct.

Getting started

Create a project in main.go and create a new manifest:

import (
        "github.com/surminus/viaduct"
)

func main() {
        // m is our manifest object
        m := viaduct.New()
}

A standard set of resources are found in the resources package.

To add them:

import (
        "github.com/surminus/viaduct"
        "github.com/surminus/viaduct/resources"
)

func main() {
        m := viaduct.New()

        m.Add(&resources.Directory{Path: "/tmp/test"})
        m.Add(&resources.File{Path: "/tmp/test/foo"})
}

All resources will run concurrently, so in this example we will declare a dependency so that the directory is created before the file:

func main() {
        m := viaduct.New()

        dir := m.Add(&resources.Directory{Path: "/tmp/test"})
        m.Add(&resources.File{Path: "/tmp/test/foo"}, dir)
}

When you've added all the resources you need, we can apply them:

func main() {
        m := viaduct.New()

        dir := m.Add(&resources.Directory{Path: "/tmp/test"})
        m.Add(&resources.File{Path: "/tmp/test/foo"}, dir)

        m.Run()
}

Compile the package and run it:

go build -o viaduct
./viaduct

See the example in the examples directory.

CLI

The compiled binary comes with runtime flags:

./viaduct --help

Embedded files and templates

There are helper functions to allow us to use the embed package to flexibly work with files and templates.

To create a template, first create a file in templates/test.txt using Go template syntax:

My cat is called {{ .Name }}

We can then generate the data to create our file:

import (
        "embed"

        "github.com/surminus/viaduct"
        "github.com/surminus/viaduct/resources"
)

//go:embed templates
var templates embed.FS

func main() {
        m := viaduct.New()

        template := resources.NewTemplate(
                templates,
                "templates/test.txt",
                struct{ Name string }{Name: "Bella"},
        )

        // CreateFile is a helper function that takes two arguments
        m.Add(resources.CreateFile("test/foo", template))
}

The EmbeddedFile function works in a similar way, but without variables.

Attributes

Like any good configuration management tool, we also have access to node attributes under the Attribute variable:

import (
        "fmt"

        "github.com/surminus/viaduct"
        "github.com/surminus/viaduct/resources"
)

func main() {
        m := viaduct.New()

        // E is an alias for creating an Execute resource
        m.Add(resources.Exec(fmt.Sprintf("echo \"Hello %s!\"", viaduct.Attribute.User.Username)))
}

Sudo support

If you require to perform actions that require sudo access, such as using the Package resource, or creating files using File, then you should run the executible using sudo.

Otherwise, assigning permissions should be achieved by explicitly setting the user and group in the resource.

Alternatively, you can set a default user attribute:

func main() {
        viaduct.Attribute.SetUser("laura")
        m := viaduct.New()

        // Will print my home directory
        m.Add(resources.Echo(viaduct.Attribute.User.Homedir))

        m.Run()
}

Using custom resources

Custom resources just need to implement the ResourceAttributes interface.

See the example custom resource in the examples directory.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Languages