Skip to content

Commit

Permalink
add config files support for wrapper modes (#9)
Browse files Browse the repository at this point in the history
  • Loading branch information
dee-kryvenko authored Apr 16, 2020
1 parent a444613 commit 77d1ad3
Show file tree
Hide file tree
Showing 7 changed files with 79 additions and 15 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [0.0.4] - 2020-04-15

### Added

- Implemented config files for wrapper mode

## [0.0.3] - 2020-04-12

### Added
Expand Down
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,16 @@ terraform-backend-git git \

`terraform-backend-git` will act as a wrapper - it will start a backend, generate `*.auto.tf` file in current working directory and fall back to terraform accordingly to your input. After done it will cleanup `*.auto.tf` file it created. The file would contain an HTTP backend configuration pointing to that backend instance, so you shouldn't be having any other backend configurations in your TF code.

Alternatively, you could use `terraform-backend-git.hcl` config file and put it in the current working directory:

```hcl
git.repository = "git@github.com:my-org/tf-state.git"
git.ref = "master"
git.state = "my/state.json"
```

You can specify custom path to `hcl` config file using `--config` arg.

Alternatively, you could have more control over the process if you are using something like `terragrunt`. Bottom line, your Terraform backend config should be looking like this:

```terraform
Expand Down
5 changes: 3 additions & 2 deletions git_backend_wrappers.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"text/template"

"github.com/spf13/cobra"
"github.com/spf13/viper"
)

// gitHTTPBackendConfigPath is a path to the backend tf config to generate
Expand All @@ -31,13 +32,13 @@ terraform {
log.Fatal(err)
}

addr := strings.Split(address, ":")
addr := strings.Split(viper.GetString("address"), ":")
p := map[string]string{
"port": addr[len(addr)-1],
}

for _, flag := range []string{"repository", "ref", "state"} {
if p[flag], err = cmd.Flags().GetString(flag); err != nil {
if p[flag] = viper.GetString("git." + flag); p[flag] == "" {
log.Fatal(err)
}
}
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ require (
github.com/go-git/go-git/v5 v5.0.0
github.com/gorilla/handlers v1.4.2
github.com/hashicorp/terraform v0.12.24
github.com/mitchellh/go-homedir v1.1.0
github.com/spf13/cobra v1.0.0
github.com/spf13/viper v1.4.0
golang.org/x/crypto v0.0.0-20200406173513-056763e48d71
Expand Down
64 changes: 55 additions & 9 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,19 @@ import (
"net/http"
"os"
"os/exec"
"strings"

"github.com/gorilla/handlers"
"github.com/mitchellh/go-homedir"
"github.com/plumber-cd/terraform-backend-git/backend"
"github.com/plumber-cd/terraform-backend-git/server"
"github.com/plumber-cd/terraform-backend-git/storages/git"
"github.com/plumber-cd/terraform-backend-git/types"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)

var (
address string
accessLogs bool
)
var cfgFile string

// rootCmd main command that just starts the server and keeps listening on port until terminated
var rootCmd = &cobra.Command{
Expand Down Expand Up @@ -66,33 +66,79 @@ func startServer() {
http.HandleFunc("/", server.HandleFunc)

var handler http.Handler
if accessLogs {
if viper.GetBool("accessLogs") {
handler = handlers.LoggingHandler(os.Stdout, http.DefaultServeMux)
} else {
handler = nil
}

address := viper.GetString("address")
log.Println("listen on", address)
log.Fatal(http.ListenAndServe(address, handler))
}

func initConfig() {
viper.SetConfigType("hcl")
viper.SetConfigName("terraform-backend-git")

if cfgFile != "" {
viper.SetConfigFile(cfgFile)
} else {
home, err := homedir.Dir()
if err != nil {
log.Fatal(err)
}
viper.AddConfigPath(home)

cwd, err := os.Getwd()
if err != nil {
log.Fatal(err)
}
viper.AddConfigPath(cwd)
}

viper.AutomaticEnv()
viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
viper.SetEnvPrefix("TF_BACKEND_GIT")

if err := viper.ReadInConfig(); err == nil {
log.Println("Using config file:", viper.ConfigFileUsed())
} else {
log.Println(err)
}
}

func main() {
// keep the output clean as in wrapper mode it'll mess out with Terraform own output
log.SetFlags(0)
log.SetPrefix("[terraform-backend-git]: ")

rootCmd.PersistentFlags().StringVarP(&address, "address", "a", "127.0.0.1:6061", "Specify the listen address")
rootCmd.PersistentFlags().BoolVarP(&accessLogs, "access-logs", "l", false, "Log HTTP requests to the console")
cobra.OnInitialize(initConfig)

rootCmd.PersistentFlags().StringVarP(&cfgFile, "config", "c", "", "config file (default is terraform-backend-git.hcl)")

rootCmd.PersistentFlags().StringP("address", "a", "127.0.0.1:6061", "Specify the listen address")
viper.BindPFlag("address", rootCmd.PersistentFlags().Lookup("address"))
viper.SetDefault("address", "127.0.0.1:6061")
rootCmd.PersistentFlags().BoolP("access-logs", "l", false, "Log HTTP requests to the console")
viper.BindPFlag("accessLogs", rootCmd.PersistentFlags().Lookup("access-logs"))
viper.SetDefault("accessLogs", false)

rootCmd.AddCommand(stopCmd)

gitBackendCmd.PersistentFlags().StringP("repository", "r", "", "Repository to use as storage")
gitBackendCmd.MarkPersistentFlagRequired("repository")
viper.BindPFlag("git.repository", gitBackendCmd.PersistentFlags().Lookup("repository"))

gitBackendCmd.PersistentFlags().StringP("ref", "b", "master", "Ref (branch) to use")
viper.BindPFlag("git.ref", gitBackendCmd.PersistentFlags().Lookup("ref"))
viper.SetDefault("git.ref", "master")

gitBackendCmd.PersistentFlags().StringP("state", "s", "", "Ref (branch) to use")
gitBackendCmd.MarkPersistentFlagRequired("state")
viper.BindPFlag("git.state", gitBackendCmd.PersistentFlags().Lookup("state"))

terraformWrapperCmd.Flags().StringP("tf", "t", "terraform", "Path to terraform binary")
viper.BindPFlag("wrapper.tf.bin", terraformWrapperCmd.Flags().Lookup("tf"))
viper.SetDefault("wrapper.tf.bin", "terraform")

// for every backend type CMD add a wrapper CMD behind
for _, backendCmd := range backendsCmds {
Expand Down
2 changes: 2 additions & 0 deletions test/tf/terraform-backend-git.hcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
git.repository = "git@github.com:plumber-cd/terraform-backend-git-fixture-state.git"
git.state = "state.json"
6 changes: 2 additions & 4 deletions tf_backend_wrapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"os/exec"

"github.com/spf13/cobra"
"github.com/spf13/viper"
)

// terraformWrapperCmd will pass all arguments to terraform,
Expand All @@ -16,10 +17,7 @@ var terraformWrapperCmd = &cobra.Command{
SilenceUsage: true,
Args: cobra.ArbitraryArgs,
RunE: func(cmd *cobra.Command, args []string) error {
tf, err := cmd.Flags().GetString("tf")
if err != nil {
return err
}
tf := viper.GetString("wrapper.tf.bin")

tfCommand := exec.Command(tf, args...)
tfCommand.Stdin = os.Stdin
Expand Down

0 comments on commit 77d1ad3

Please sign in to comment.