ssm

package module
v0.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 29, 2019 License: MIT Imports: 9 Imported by: 0

README

ssm

github actions godoc goreportcard codecov

Read config values from AWS System Manager Parameter Store by names defined using struct tags.

Example

Parameters stored in SSM:

/dev
  /database
    /username
    /password
    /host
    /port
    /name
  /auth0
    /domain
    /client_id
    /client_secret
  /another
    /...
/prod
  ...

Read the required dev values:

params := ssm.NewParamStore(
    ssm.WithPrefix("dev"),
    ssm.WithDecryption(true),
)

type Config struct {
    DB struct {
        User string `ssm:"username"`
        Pass string `ssm:"password"`
        Host string `ssm:"host"`
        Port int    `ssm:"port"`
        Name string `ssm:"name"`
    } `ssm:"database"`
    Auth0 struct {
        ClientID     string `ssm:"client_id"`
        ClientSecret string `ssm:"client_secret"`
    } `ssm:"auth0"`
    // Fields not included are not read from SSM
}

var cfg Config
if err := params.Read(context.Background(), &cfg); err != nil {
    // Handle error
}

// cfg is now ready to use

See GoDoc for more details.

Documentation

Overview

Package ssm provides a way to read config values from AWS Systems Manager Parameter Store.

Struct tags

Struct tags determine what parameters to get from SSM:

type Config struct {
    Host     string `ssm:"host"`
    User     string `ssm:"user"`
    Password string `ssm:"password"`
    Port     int    `ssm:"port"`
    Name     string `ssm:"name"`
    Scheme   string `ssm:"scheme"`
}

The name of the struct tag to use can be set by passing WithTag to NewParamStore. Defaults to `ssm`.

Nested values

Nested struct value are allowed. When present, the name to read from SSM is constructed by the path to the value:

type Config struct {
    DynamoDB struct {
        Table string `ssm:"table"`                  // /dynamo_db/table
    } `ssm:"dynamo_db"`
    Auth0 struct {
        ClientID     string   `ssm:"client_id"`     // /auth0/client_id
        ClientSecret string   `ssm:"client_secret"` // /auth0/client_secret
        Domain       string   `ssm:"domain"`        // /auth0/domain
        Scope        []string `ssm:"scope"`         // /auth0/scope
    } `ssm:"auth0"`
}

Options

The behavior can be modified by passing options to NewParamStore. If no options are passed, the external aws config is read for the SSM client, and ssm is used as the struct tag.

WithPrefix allows all keys to be prefixed with a value. Given the following structure in SSM:

/
  /dev
    /myapp
      /db
        /user
        /pass

The values can be read for myapp using WithPrefix("dev/myapp"):

type Config struct {
    DB struct {
        User string `ssm:"user"`
        Pass string `ssm:"user"`
    } `ssm:"db"`
}

WithDecryption(true) allows decrypting encrypted SecureString parameters. The caller must have access to use the attached KMS key to decrypt the values.

Times and durations can be parsed using WithParseTime and WithParseDuration.

Slices

If the parameter type is StringList, the value can be assigned to a slice. Conversion rules apply to items within the slice, allowing for example []int to be used.

https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-parameter-store.html

Example
package main

import (
	"context"
	"log"

	"github.com/akupila/ssm"
)

func main() {
	type Config struct {
		Key string `ssm:"key"`
	}

	params, err := ssm.NewParamStore()
	if err != nil {
		log.Fatal(err)
	}

	var cfg Config
	if err := params.Read(context.Background(), &cfg); err != nil {
		log.Fatal(err)
	}

	// cfg.Key will now be the value of /key in ssm parameter store
}
Output:

Example (Nested)
package main

import (
	"context"
	"log"

	"github.com/akupila/ssm"
)

func main() {
	type Config struct {
		DB struct {
			Host string `ssm:"host"`
			User string `ssm:"user"`
			Pass string `ssm:"password"`
			Port int    `ssm:"port"`
			Name string `ssm:"name"`
		} `ssm:"database"`
		Auth0 struct {
			ClientID     string `ssm:"client_id"`
			ClientSecret string `ssm:"client_secret"`
			Domain       string `ssm:"domain"`
		} `ssm:"auth0"`
	}

	params, err := ssm.NewParamStore(
		ssm.WithPrefix("dev"),
		ssm.WithDecryption(true),
	)
	if err != nil {
		log.Fatal(err)
	}

	var cfg Config
	if err := params.Read(context.Background(), &cfg); err != nil {
		log.Fatal(err)
	}
}
Output:

Example (Options)
package main

import (
	"context"
	"log"

	"github.com/akupila/ssm"
)

func main() {
	type Config struct {
		Key string `config:"key"`
	}

	params, err := ssm.NewParamStore(
		ssm.WithPrefix("dev"),
		ssm.WithDecryption(true),
		ssm.WithTag("config"),
	)
	if err != nil {
		log.Fatal(err)
	}

	var cfg Config
	if err := params.Read(context.Background(), &cfg); err != nil {
		log.Fatal(err)
	}

	// cfg.Key will now be the value of /dev/key in ssm parameter store
}
Output:

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Client

type Client interface {
	GetParametersRequest(input *ssm.GetParametersInput) ssm.GetParametersRequest
}

Client is the SSM client.

type Option

type Option func(s *ParamStore)

An Option sets a configuration option in the ParamStore.

func WithClient

func WithClient(client Client) Option

WithClient sets the SSM client to use.

func WithDecryption

func WithDecryption(enabled bool) Option

WithDecryption determines whether SecureString parameters should be decrypted.

If WithDecryption is not set (or is set to false), SecureString values will return the encrypted value.

The role must have access to decrypt the values using the KMS key they were encrypted with.

https://docs.aws.amazon.com/systems-manager/latest/userguide/sysman-paramstore-securestring.html https://docs.aws.amazon.com/kms/latest/developerguide/services-parameter-store.html

func WithParseDuration

func WithParseDuration() Option

WithParseDuration parses a duration string to a time.Duration.

Example
package main

import (
	"context"
	"log"
	"time"

	"github.com/akupila/ssm"
)

func main() {
	type Config struct {
		Timeout time.Duration `ssm:"timeout"`
	}

	params, err := ssm.NewParamStore(
		ssm.WithParseDuration(),
	)
	if err != nil {
		log.Fatal(err)
	}

	var cfg Config
	if err := params.Read(context.Background(), &cfg); err != nil {
		log.Fatal(err)
	}
}
Output:

func WithParseNumber

func WithParseNumber() Option

WithParseNumber enables parsing strings and lists of strings to ints and floats.

Example
package main

import (
	"context"
	"log"

	"github.com/akupila/ssm"
)

func main() {
	type Config struct {
		Integer int     `ssm:"a"`
		Float   float64 `ssm:"b"`
	}

	params, err := ssm.NewParamStore(
		ssm.WithParseNumber(),
	)
	if err != nil {
		log.Fatal(err)
	}

	var cfg Config
	if err := params.Read(context.Background(), &cfg); err != nil {
		log.Fatal(err)
	}
}
Output:

func WithParseTime

func WithParseTime(layout string) Option

WithParseTime parses a time string with the given layout to a time.Time.

Example
package main

import (
	"context"
	"log"
	"time"

	"github.com/akupila/ssm"
)

func main() {
	type Config struct {
		Time time.Time `ssm:"timeout"`
	}

	params, err := ssm.NewParamStore(
		ssm.WithParseTime(time.RFC3339),
	)
	if err != nil {
		log.Fatal(err)
	}

	var cfg Config
	if err := params.Read(context.Background(), &cfg); err != nil {
		log.Fatal(err)
	}
}
Output:

func WithPrefix

func WithPrefix(prefix string) Option

WithPrefix sets the prefix to use for all keys.

WithPrefix("dev")
WithPrefix("prod/app/db")
WithPrefix("test/auth/token")

The prefix may contain a single / at the beginning or end.

func WithTag

func WithTag(tag string) Option

WithTag sets the struct tag to use for resolving schema.

Example
package main

import (
	"context"
	"log"

	"github.com/akupila/ssm"
)

func main() {
	type Config struct {
		Username string `config:"username"`
		Password string `config:"password"`
	}

	params, err := ssm.NewParamStore(
		ssm.WithTag("config"),
	)
	if err != nil {
		log.Fatal(err)
	}

	var cfg Config
	if err := params.Read(context.Background(), &cfg); err != nil {
		log.Fatal(err)
	}
}
Output:

type ParamStore

type ParamStore struct {
	// contains filtered or unexported fields
}

ParamStore reads configuration values from SSM Parameter Store.

func NewParamStore

func NewParamStore(options ...Option) (*ParamStore, error)

NewParamStore creates a new parameter store.

If WithTag was not passed, `ssm` is used as struct tag.

func (*ParamStore) Read

func (s *ParamStore) Read(ctx context.Context, target interface{}) error

Read reads configuration values into the given target.

The target must be a non-nil pointer to a struct.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL