Add vault function for HCL2 and document
This commit is contained in:
parent
027eb40a97
commit
33e3f62ff7
1
go.sum
1
go.sum
|
@ -621,6 +621,7 @@ github.com/zclconf/go-cty v1.0.0/go.mod h1:xnAOWiHeOqg2nWS62VtQ7pbOu17FtxJNW8RLE
|
|||
github.com/zclconf/go-cty v1.2.0/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8=
|
||||
github.com/zclconf/go-cty v1.4.0 h1:+q+tmgyUB94HIdH/uVTIi/+kt3pt4sHwEZAcTyLoGsQ=
|
||||
github.com/zclconf/go-cty v1.4.0/go.mod h1:nHzOclRkoj++EU9ZjSrZvRG0BXIWt8c7loYc0qXAFGQ=
|
||||
github.com/zclconf/go-cty v1.5.1 h1:oALUZX+aJeEBUe2a1+uD2+UTaYfEjnKFDEMRydkGvWE=
|
||||
github.com/zclconf/go-cty-yaml v1.0.1 h1:up11wlgAaDvlAGENcFDnZgkn0qUJurso7k6EpURKNF8=
|
||||
github.com/zclconf/go-cty-yaml v1.0.1/go.mod h1:IP3Ylp0wQpYm50IHK8OZWKMu6sPJIUgKa8XhiVHura0=
|
||||
go.opencensus.io v0.21.0 h1:mU6zScU4U1YAFPHEHYk+3JC4SY7JxgkqS10ZOSyksNg=
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
package function
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/zclconf/go-cty/cty"
|
||||
"github.com/zclconf/go-cty/cty/function"
|
||||
|
||||
vaultapi "github.com/hashicorp/vault/api"
|
||||
)
|
||||
|
||||
// VaultFunc constructs a function that retrieves KV secrets from HC vault
|
||||
var VaultFunc = function.New(&function.Spec{
|
||||
Params: []function.Parameter{
|
||||
{
|
||||
Name: "path",
|
||||
Type: cty.String,
|
||||
},
|
||||
{
|
||||
Name: "key",
|
||||
Type: cty.String,
|
||||
},
|
||||
},
|
||||
Type: function.StaticReturnType(cty.String),
|
||||
Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
|
||||
|
||||
path := args[0].AsString()
|
||||
key := args[1].AsString()
|
||||
|
||||
if token := os.Getenv("VAULT_TOKEN"); token == "" {
|
||||
return cty.StringVal(""), errors.New("Must set VAULT_TOKEN env var in order to " +
|
||||
"use vault template function")
|
||||
}
|
||||
|
||||
vaultConfig := vaultapi.DefaultConfig()
|
||||
cli, err := vaultapi.NewClient(vaultConfig)
|
||||
if err != nil {
|
||||
return cty.StringVal(""), fmt.Errorf("Error getting Vault client: %s", err)
|
||||
}
|
||||
secret, err := cli.Logical().Read(path)
|
||||
if err != nil {
|
||||
return cty.StringVal(""), fmt.Errorf("Error reading vault secret: %s", err)
|
||||
}
|
||||
if secret == nil {
|
||||
return cty.StringVal(""), errors.New("Vault Secret does not exist at the given path")
|
||||
}
|
||||
|
||||
data, ok := secret.Data["data"]
|
||||
if !ok {
|
||||
// maybe ths is v1, not v2 kv store
|
||||
value, ok := secret.Data[key]
|
||||
if ok {
|
||||
return cty.StringVal(value.(string)), nil
|
||||
}
|
||||
|
||||
// neither v1 nor v2 proudced a valid value
|
||||
return cty.StringVal(""), fmt.Errorf("Vault data was empty at the "+
|
||||
"given path. Warnings: %s", strings.Join(secret.Warnings, "; "))
|
||||
}
|
||||
|
||||
value := data.(map[string]interface{})[key].(string)
|
||||
return cty.StringVal(value), nil
|
||||
},
|
||||
})
|
||||
|
||||
// Vault returns a secret from a KV store in HC vault
|
||||
func Vault() (cty.Value, error) {
|
||||
return VaultFunc.Call([]cty.Value{})
|
||||
}
|
|
@ -106,6 +106,7 @@ func Functions(basedir string) map[string]function.Function {
|
|||
"uuidv4": uuid.V4Func,
|
||||
"uuidv5": uuid.V5Func,
|
||||
"values": stdlib.ValuesFunc,
|
||||
"vault": pkrfunction.VaultFunc,
|
||||
"yamldecode": ctyyaml.YAMLDecodeFunc,
|
||||
"yamlencode": ctyyaml.YAMLEncodeFunc,
|
||||
"zipmap": stdlib.ZipmapFunc,
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
layout: docs
|
||||
page_title: vault - Functions - Configuration Language
|
||||
sidebar_title: vault Functions
|
||||
description: Overview of available vault functions
|
||||
---
|
|
@ -0,0 +1,69 @@
|
|||
---
|
||||
layout: docs
|
||||
page_title: vault - Functions - Configuration Language
|
||||
sidebar_title: vault
|
||||
description: The vault function retrieves secrets from HashiCorp Vault KV stores.
|
||||
--
|
||||
|
||||
# `vault` Function
|
||||
|
||||
Secrets can be read from [Vault](https://www.vaultproject.io/) and used within
|
||||
your template as user variables. the `vault` function is available _only_
|
||||
within the default value of a user variable, allowing you to default a user
|
||||
variable to a vault secret.
|
||||
|
||||
An example of using a v2 kv engine:
|
||||
|
||||
If you store a value in vault using `vault kv put secret/hello foo=world`, you
|
||||
can access it using the following:
|
||||
|
||||
```hcl
|
||||
vault("/secret/data/hello" "foo")
|
||||
```
|
||||
|
||||
which will assign "my_secret": "world"
|
||||
|
||||
An example of using a v1 kv engine:
|
||||
|
||||
If you store a value in vault using:
|
||||
|
||||
vault secrets enable -version=1 -path=secrets kv
|
||||
vault kv put secrets/hello foo=world
|
||||
|
||||
You can access it using the following:
|
||||
|
||||
```hcl
|
||||
vault("secrets/hello", "foo")
|
||||
```
|
||||
|
||||
This example accesses the Vault path `secret/data/foo` and returns the value
|
||||
stored at the key `bar`, storing it as "my_secret".
|
||||
|
||||
In order for this to work, you must set the environment variables `VAULT_TOKEN`
|
||||
and `VAULT_ADDR` to valid values.
|
||||
|
||||
The api tool we use allows for more custom configuration of the Vault client via
|
||||
environment variables.
|
||||
|
||||
The full list of available environment variables is:
|
||||
|
||||
```text
|
||||
"VAULT_ADDR"
|
||||
"VAULT_AGENT_ADDR"
|
||||
"VAULT_CACERT"
|
||||
"VAULT_CAPATH"
|
||||
"VAULT_CLIENT_CERT"
|
||||
"VAULT_CLIENT_KEY"
|
||||
"VAULT_CLIENT_TIMEOUT"
|
||||
"VAULT_SKIP_VERIFY"
|
||||
"VAULT_NAMESPACE"
|
||||
"VAULT_TLS_SERVER_NAME"
|
||||
"VAULT_WRAP_TTL"
|
||||
"VAULT_MAX_RETRIES"
|
||||
"VAULT_TOKEN"
|
||||
"VAULT_MFA"
|
||||
"VAULT_RATE_LIMIT"
|
||||
```
|
||||
|
||||
and detailed documentation for usage of each of those variables can be found
|
||||
[here](https://www.vaultproject.io/docs/commands/#environment-variables).
|
Loading…
Reference in New Issue