diff --git a/Dockerfile b/Dockerfile index d8352c3..9690cf4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -28,6 +28,10 @@ ARG terraform_version RUN wget -q https://releases.hashicorp.com/terraform/${terraform_version}/terraform_${terraform_version}_linux_amd64.zip -O terraform.zip && \ unzip terraform.zip -d /bin && \ rm -f terraform.zip +ARG summarize_version +RUN curl -sL https://github.com/dineshba/tf-summarize/releases/download/v${summarize_version}/tf-summarize_linux_amd64.zip -osummarize.zip && \ + unzip summarize.zip tf-summarize -d /bin && \ + rm -f summarize.zip COPY --from=builder /go/bin/drone-terraform /bin/ ENTRYPOINT ["/bin/drone-terraform"] diff --git a/build-docker.sh b/build-docker.sh index 4b23861..9e0f599 100755 --- a/build-docker.sh +++ b/build-docker.sh @@ -13,11 +13,13 @@ major=$(echo $tag | awk -F. '{print $1}') minor=$(echo $tag | awk -F. '{print $2}') tf_ver="1.0.2" +sum_ver="0.2.2" echo "Confirm building images for:" echo " MAJOR: ${major}" echo " MINOR: ${minor}" echo " TF_VERSION: ${tf_ver}" +echo " SUM_VERSION: ${sum_ver}" read -p "Proceed? [Y/N] " ans @@ -27,7 +29,7 @@ if [[ "$ans" != "Y" && "$ans" != "y" ]]; then fi set -x -docker build -t jmccann/drone-terraform:latest --build-arg terraform_version=${tf_ver} . +docker build -t jmccann/drone-terraform:latest --build-arg terraform_version=${tf_ver} --build-arg summarize_version=${sum_ver}. docker tag jmccann/drone-terraform:latest jmccann/drone-terraform:${major} docker tag jmccann/drone-terraform:latest jmccann/drone-terraform:${major}.${minor} diff --git a/main.go b/main.go index d396e76..bf63671 100644 --- a/main.go +++ b/main.go @@ -44,6 +44,11 @@ func main() { Usage: "options for the init command. See https://www.terraform.io/docs/commands/init.html", EnvVar: "PLUGIN_INIT_OPTIONS", }, + cli.StringFlag{ + Name: "summarize_options", + Usage: "options for the tf-summarize command. See https://github.com/dineshba/tf-summarize#usage", + EnvVar: "PLUGIN_SUMMARIZE_OPTIONS", + }, cli.StringFlag{ Name: "fmt_options", Usage: "options for the fmt command. See https://www.terraform.io/docs/commands/fmt.html", @@ -54,6 +59,16 @@ func main() { Usage: "The number of concurrent operations as Terraform walks its graph", EnvVar: "PLUGIN_PARALLELISM", }, + cli.BoolFlag{ + Name: "skip_init", + Usage: "skip terraform init (useful for usage with s3-cache)", + EnvVar: "PLUGIN_SKIP_INIT", + }, + cli.BoolFlag{ + Name: "skip_cleanup", + Usage: "skip removal of .terraform/ (useful for usage with s3-cache)", + EnvVar: "PLUGIN_SKIP_CLEANUP", + }, cli.StringFlag{ Name: "netrc.machine", Usage: "netrc machine", @@ -152,6 +167,8 @@ func run(c *cli.Context) error { json.Unmarshal([]byte(c.String("init_options")), &initOptions) fmtOptions := FmtOptions{} json.Unmarshal([]byte(c.String("fmt_options")), &fmtOptions) + summarizeOptions := SummarizeOptions{} + json.Unmarshal([]byte(c.String("summarize_options")), &summarizeOptions) plugin := Plugin{ Config: Config{ @@ -160,10 +177,13 @@ func run(c *cli.Context) error { Secrets: secrets, InitOptions: initOptions, FmtOptions: fmtOptions, + SummarizeOptions: summarizeOptions, Cacert: c.String("ca_cert"), Sensitive: c.Bool("sensitive"), RoleARN: c.String("role_arn_to_assume"), RootDir: c.String("root_dir"), + SkipInit: c.Bool("skip_init"), + SkipCleanup: c.Bool("skip_cleanup"), Parallelism: c.Int("parallelism"), Targets: c.StringSlice("targets"), VarFiles: c.StringSlice("var_files"), diff --git a/plugin.go b/plugin.go index 6646fcf..79253c7 100644 --- a/plugin.go +++ b/plugin.go @@ -26,8 +26,11 @@ type ( Secrets map[string]string InitOptions InitOptions FmtOptions FmtOptions + SummarizeOptions SummarizeOptions Cacert string Sensitive bool + SkipInit bool + SkipCleanup bool RoleARN string RootDir string Parallelism int @@ -59,6 +62,14 @@ type ( Check *bool `json:"check"` } + // SummarizeOptions for tf-summarize + SummarizeOptions struct { + Draw *bool `json:"draw"` + Md *bool `json:"md"` + Tree *bool `json:"tree"` + SeparateTree *bool `json:"separate_tree"` + } + // Plugin represents the plugin instance to be executed Plugin struct { Config Config @@ -104,9 +115,11 @@ func (p Plugin) Exec() error { commands = append(commands, installCaCert(p.Config.Cacert)) } - commands = append(commands, deleteCache(terraformDataDir)) - commands = append(commands, initCommand(p.Config.InitOptions)) - commands = append(commands, getModules()) + if !p.Config.SkipInit { + commands = append(commands, deleteCache(terraformDataDir)) + commands = append(commands, initCommand(p.Config.InitOptions)) + commands = append(commands, getModules()) + } // Add commands listed from Actions for _, action := range p.Config.Actions { @@ -119,6 +132,8 @@ func (p Plugin) Exec() error { commands = append(commands, tfPlan(p.Config, false)) case "plan-destroy": commands = append(commands, tfPlan(p.Config, true)) + case "summarize": + commands = append(commands, tfSummary(p.Config)) case "apply": commands = append(commands, tfApply(p.Config)) case "destroy": @@ -128,7 +143,9 @@ func (p Plugin) Exec() error { } } - commands = append(commands, deleteCache(terraformDataDir)) + if !p.Config.SkipCleanup { + commands = append(commands, deleteCache(terraformDataDir)) + } for _, c := range commands { if c.Dir == "" { @@ -331,6 +348,48 @@ func tfPlan(config Config, destroy bool) *exec.Cmd { ) } +func tfSummary(config Config) *exec.Cmd { + json_cmd := exec.Command("terraform", "show", "-json", getTfoutPath()) + json_path := fmt.Sprintf("%s.json", getTfoutPath()) + + json_file, err := os.Create(json_path) + if err != nil { + logrus.WithFields(logrus.Fields{ + "error": err, + }).Fatal("Failed to create JSON state file") + } + logrus.Debug("JSON state file created successfully") + + json_cmd.Stdout = json_file + defer json_file.Close() + + err = json_cmd.Run() + if err != nil { + logrus.WithFields(logrus.Fields{ + "error": err, + }).Fatal("Failed to execute a command") + } + + var args []string + + if config.SummarizeOptions.Draw != nil { + args = append(args, "-draw") + } + if config.SummarizeOptions.Md != nil { + args = append(args, "-md") + } + if config.SummarizeOptions.Tree != nil { + args = append(args, "-tree") + } + if config.SummarizeOptions.SeparateTree != nil { + args = append(args, "-separate-tree") + } + + args = append(args, json_path) + + return exec.Command("tf-summarize", args...) +} + func tfValidate() *exec.Cmd { return exec.Command( "terraform",