mirror of
https://github.com/adammck/terraform-inventory
synced 2024-11-22 15:52:01 +01:00
Add support for remote state (#60)
* add support for remote state in version 0.9 * remove .terraform/terraform.tfstate as a source
This commit is contained in:
parent
898a7270c4
commit
313d404eb3
16
README.md
16
README.md
@ -94,11 +94,25 @@ Can be provisioned separately with:
|
||||
## More Usage
|
||||
|
||||
Ansible doesn't seem to support calling a dynamic inventory script with params,
|
||||
so if you need to specify the location of your state file, set the `TF_STATE`
|
||||
so if you need to specify the location of your state file or terraform directory, set the `TF_STATE`
|
||||
environment variable before running `ansible-playbook`, like:
|
||||
|
||||
|
||||
TF_STATE=deploy/terraform.tfstate ansible-playbook --inventory-file=/path/to/terraform-inventory deploy/playbook.yml
|
||||
|
||||
or
|
||||
|
||||
TF_STATE=../terraform ansible-playbook --inventory-file=/path/to/terraform-inventory deploy/playbook.yml
|
||||
|
||||
If `TF_STATE` is a file, it parses the file as json, if `TF_STATE` is a directory, it runs `terraform state pull` inside the directory, which is supports both local and remote terraform state.
|
||||
|
||||
It looks for state config in this order
|
||||
|
||||
- `TF_STATE`: environment variable of where to find either a statefile or a terraform project
|
||||
- `TI_TFSTATE`: another environment variable similar to TF_STATE
|
||||
- `terraform.tfstate`: it looks in the state file in the current directory.
|
||||
- `.`: lastly it assumes you are at the root of a terraform project.
|
||||
|
||||
Alternately, if you need to do something fancier (like downloading your state
|
||||
file from S3 before running), you might wrap this tool with a shell script, and
|
||||
call that instead. Something like:
|
||||
|
8
input.go
8
input.go
@ -25,11 +25,5 @@ func GetInputPath(fs vfs.Filesystem, env venv.Env) string {
|
||||
return fn
|
||||
}
|
||||
|
||||
fn = ".terraform/terraform.tfstate"
|
||||
_, err = fs.Stat(fn)
|
||||
if err == nil {
|
||||
return fn
|
||||
}
|
||||
|
||||
return ""
|
||||
return "."
|
||||
}
|
||||
|
@ -13,11 +13,12 @@ import (
|
||||
)
|
||||
|
||||
func TestGetInputPath(t *testing.T) {
|
||||
assert.Equal(t, "", GetInputPath(memfs.Create(), venv.Mock()))
|
||||
assert.Equal(t, ".", GetInputPath(memfs.Create(), venv.Mock()))
|
||||
assert.Equal(t, "aaa", GetInputPath(memfs.Create(), envWith(map[string]string{"TF_STATE": "aaa"})))
|
||||
assert.Equal(t, "bbb", GetInputPath(memfs.Create(), envWith(map[string]string{"TI_TFSTATE": "bbb"})))
|
||||
assert.Equal(t, "terraform.tfstate", GetInputPath(fsWithFiles([]string{"terraform.tfstate"}), venv.Mock()))
|
||||
assert.Equal(t, ".terraform/terraform.tfstate", GetInputPath(fsWithFiles([]string{".terraform/terraform.tfstate"}), venv.Mock()))
|
||||
assert.Equal(t, ".", GetInputPath(fsWithFiles([]string{".terraform/terraform.tfstate"}), venv.Mock()))
|
||||
assert.Equal(t, "terraform", GetInputPath(fsWithDirs([]string{"terraform"}), envWith(map[string]string{"TF_STATE": "terraform"})))
|
||||
}
|
||||
|
||||
func envWith(env map[string]string) venv.Env {
|
||||
@ -53,6 +54,21 @@ func fsWithFiles(filenames []string) vfs.Filesystem {
|
||||
return fs
|
||||
}
|
||||
|
||||
func fsWithDirs(dirs []string) vfs.Filesystem {
|
||||
fs := memfs.Create()
|
||||
|
||||
var err error
|
||||
|
||||
for _, fp := range dirs {
|
||||
err = vfs.MkdirAll(fs, fp, 0700)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
return fs
|
||||
}
|
||||
|
||||
// TODO: Upgrade this later with file contents.
|
||||
func touchFile(fs vfs.Filesystem, filename string) error {
|
||||
return writeFile(fs, filename, []byte{}, 0600)
|
||||
|
58
main.go
58
main.go
@ -1,11 +1,13 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"flag"
|
||||
"fmt"
|
||||
"github.com/adammck/venv"
|
||||
"github.com/blang/vfs"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
@ -23,17 +25,13 @@ func main() {
|
||||
return
|
||||
}
|
||||
|
||||
fs := vfs.OS()
|
||||
if file == "" {
|
||||
fs := vfs.OS()
|
||||
|
||||
env := venv.OS()
|
||||
file = GetInputPath(fs, env)
|
||||
}
|
||||
|
||||
if file == "" {
|
||||
fmt.Printf("Usage: %s [options] path\n", os.Args[0])
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if !*list && *host == "" && !*inventory {
|
||||
fmt.Fprint(os.Stderr, "Either --host or --list must be specified")
|
||||
os.Exit(1)
|
||||
@ -45,17 +43,53 @@ func main() {
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
stateFile, err := os.Open(path)
|
||||
defer stateFile.Close()
|
||||
f, err := fs.Stat(path)
|
||||
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Error opening tfstate file: %s\n", err)
|
||||
fmt.Fprintf(os.Stderr, "Invalid file: %s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
var s state
|
||||
err = s.read(stateFile)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Error reading tfstate file: %s\n", err)
|
||||
|
||||
if !f.IsDir() {
|
||||
stateFile, err := os.Open(path)
|
||||
defer stateFile.Close()
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Error opening tfstate file: %s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
err = s.read(stateFile)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Error reading tfstate file: %s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
if f.IsDir() {
|
||||
cmd := exec.Command("terraform", "state", "pull")
|
||||
cmd.Dir = path
|
||||
var out bytes.Buffer
|
||||
cmd.Stdout = &out
|
||||
|
||||
err = cmd.Run()
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Error running `terraform state pull` in directory %s, %s\n", path, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
err = s.read(&out)
|
||||
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Error reading `terraform state pull` output: %s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if s.Modules == nil {
|
||||
fmt.Printf("Usage: %s [options] path\npath: this is either a path to a state file or a folder from which `terraform commands` are valid\n", os.Args[0])
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user