Add consul_key function to integrate concul with hcl2 tempaltes. (#10119)

* Add consul_key function to integrate concul with hcl2 tempaltes.
* sidebar nav
This commit is contained in:
Megan Marsh 2020-10-19 05:07:13 -07:00 committed by GitHub
parent 4f5e878a17
commit cc7dbf6092
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 97 additions and 24 deletions

View File

@ -8,6 +8,7 @@ import (
"strings"
"sync"
consulapi "github.com/hashicorp/consul/api"
vaultapi "github.com/hashicorp/vault/api"
)
@ -61,3 +62,27 @@ func Vault(path string, key string) (string, error) {
}
return "", errors.New("Vault path does not contain the requested key")
}
func Consul(k string) (string, error) {
consulConfig := consulapi.DefaultConfig()
client, err := consulapi.NewClient(consulConfig)
if err != nil {
return "", fmt.Errorf("error getting consul client: %s", err)
}
q := &consulapi.QueryOptions{}
kv, _, err := client.KV().Get(k, q)
if err != nil {
return "", fmt.Errorf("error reading consul key: %s", err)
}
if kv == nil {
return "", fmt.Errorf("key does not exist at the given path: %s", k)
}
value := string(kv.Value)
if value == "" {
return "", fmt.Errorf("value is empty at path %s", k)
}
return value, nil
}

View File

@ -0,0 +1,25 @@
package function
import (
"github.com/zclconf/go-cty/cty"
"github.com/zclconf/go-cty/cty/function"
commontpl "github.com/hashicorp/packer/common/template"
)
// ConsulFunc constructs a function that retrieves KV secrets from HC vault
var ConsulFunc = function.New(&function.Spec{
Params: []function.Parameter{
{
Name: "key",
Type: cty.String,
},
},
Type: function.StaticReturnType(cty.String),
Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
key := args[0].AsString()
val, err := commontpl.Consul(key)
return cty.StringVal(val), err
},
})

View File

@ -46,6 +46,7 @@ func Functions(basedir string) map[string]function.Function {
"coalescelist": stdlib.CoalesceListFunc,
"compact": stdlib.CompactFunc,
"concat": stdlib.ConcatFunc,
"consul_key": pkrfunction.ConsulFunc,
"contains": stdlib.ContainsFunc,
"convert": typeexpr.ConvertFunc,
"csvdecode": stdlib.CSVDecodeFunc,

View File

@ -10,7 +10,6 @@ import (
"text/template"
"time"
consulapi "github.com/hashicorp/consul/api"
commontpl "github.com/hashicorp/packer/common/template"
"github.com/hashicorp/packer/common/uuid"
"github.com/hashicorp/packer/helper/common"
@ -250,34 +249,14 @@ func funcGenPackerVersion(ctx *Context) interface{} {
}
func funcGenConsul(ctx *Context) interface{} {
return func(k string) (string, error) {
return func(key string) (string, error) {
if !ctx.EnableEnv {
// The error message doesn't have to be that detailed since
// semantic checks should catch this.
return "", errors.New("consul_key is not allowed here")
}
consulConfig := consulapi.DefaultConfig()
client, err := consulapi.NewClient(consulConfig)
if err != nil {
return "", fmt.Errorf("error getting consul client: %s", err)
}
q := &consulapi.QueryOptions{}
kv, _, err := client.KV().Get(k, q)
if err != nil {
return "", fmt.Errorf("error reading consul key: %s", err)
}
if kv == nil {
return "", fmt.Errorf("key does not exist at the given path: %s", k)
}
value := string(kv.Value)
if value == "" {
return "", fmt.Errorf("value is empty at path %s", k)
}
return value, nil
return commontpl.Consul(key)
}
}

View File

@ -33,6 +33,7 @@ export default [
category: 'contextual',
content: [
'vault',
'consul',
],
},
{

View File

@ -0,0 +1,42 @@
---
layout: docs
page_title: consul - Functions - Configuration Language
sidebar_title: consul
description: The consul function retrieves secrets from HashiCorp consul KV stores.
---
# `consul_key` Function
[Consul](https://www.consul.io) keys can be used within your template using the
`consul_key` function.
You can either use this function in a locals block or directly inline where you
want to use the value.
```hcl
locals {
my_version = "${consul_key("myservice/version")}"
}
source "null" "first-example" {
communicator = "none"
}
build {
name = "my-build-name"
sources = ["null.first-example"]
provisioner "shell-local" {
environment_vars = ["TESTVAR=${build.PackerRunUUID}"]
inline = ["echo my_version is '${local.my_version}'",
"echo version is '${consul_key("myservice/version")}'."]
}
}
```
This will load the key stored at the path `myservice/version` from consul.
The configuration for consul (address, tokens, ...) must be specified as
environment variables, as specified in the
[Documentation](https://www.consul.io/docs/commands#environment-variables).