Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/dontlaugh/packer-plugin-cue

Render files in your Packer builds with CUE
https://github.com/dontlaugh/packer-plugin-cue

cue packer packer-plugin packer-provisioner

Last synced: 3 months ago
JSON representation

Render files in your Packer builds with CUE

Awesome Lists containing this project

README

        

# packer-plugin-cue

A packer plugin that writes files to the image you're provisioning, based
on values extracted from a CUE module.

A Packer data provider is TODO.

## Provided Plugins

Provisioners:

* `cue-export` - Given a module, package, and an optional CUE expression, the
provisioner writes a file with the scalar value or struct yielded by `cue export`.

## Example Usage

Add this plugin to `required_plugins`

```hcl
packer {
required_plugins {
cue = {
version = ">=0.3.1"
source = "github.com/dontlaugh/cue"
}
}
}

```

Write the data yielded by the expression `world` in package `hello` to **/tmp/some-file**

```hcl
provisioner "cue-export" {
dir = "."
package = "hello"
expression = "world"
dest = "/tmp/some-file"
}
```

## Config Attributes

Provisioners:

`cue-export`

* dir - path to where the CUE evaluation should take place
* module - (optional) name of module
* package - (optional) package name, if required to disambiguate
* expression - (optional) CUE expression that yields a specific package value
* dest - path to destination file; Note that some Packer builders
will not automatically create ancestor directories.
* tags - (optional) list of strings of the form `key=value`

## Explanation

Let's say you have a CUE module with a file **my_service.cue** that looks like this

```cue
package systemd

config_file: "/etc/my-service/config.yaml"

unit_file: '''
[Unit]
Description=My example service

[Service]
Environment=MY_CONFIG=\(config_file)
ExecStart=/usr/bin/my-service

[Install]
WantedBy=multi-user.target
'''
```

Invoking `cue export -p systemd ./my_service.cue` gives you the entire package as JSON

```json
{
"config_file": "/etc/my-service/config.yaml",
"unit_file": "W1VuaXRdCkRlc2N...=="
}
```
_Note: We've elided most of the unit file's base64 string here._

Providing `--out binary` and `-e unit_file` lets us select the `unit_file`
field and render it. The value of `config_file` is interpolated.

```
$ cue export -p systemd -e unit_file --out binary ./my_service.cue
[Unit]
Description=My example service

[Service]
Environment=MY_CONFIG=/etc/my-service/config.yaml
ExecStart=/usr/bin/my-service

[Install]
WantedBy=multi-user.target
```

This manner of templating files and interpolating values is useful for machine
image provisioning, and this plugin provides a declarative API for rendering CUE
to files during a Packer build.

The previous examples use the `cue` CLI, which you should definitely download
and experiment with if you are unfamiliar with CUE. This plugin, however, uses
CUE as a Go library.

### But wait, there's more!

The `cue-export` provisioner doesn't need a string or binary template to write
files. If the package (with optional expression) evaluates to a string, number,
or struct type, this plugin does the following

* String and number types are written as a single-line file to `dest`
* Struct types must be given a `serialize` config, one of "json", "yaml",
or "toml". The entire struct will be serialized in tha format.

A quick example of a struct rendered to yaml

```hcl
provisioner "cue-export" {
module = "."
dir = "."
package = "prometheus"
expression = "config_yaml"
serialize = "yaml"
dest = "/tmp/prometheus.yaml"
}
```

If your expression evaluates to a struct and no serializer is set, it's an error.