From 4197abea8d0414749cefd2eecfe16a2f3e9dcbaf Mon Sep 17 00:00:00 2001 From: edwinavalos Date: Tue, 20 Dec 2016 19:43:45 -0600 Subject: [PATCH] Adding targets section for configuration (#30) * Adding targets section for configuration Will add a --target for each item in a comma separated list to the plan and apply commands Updated the docs to show the new behavior. If left undefined there is no regression in functionality. * Combine the --target append steps No reason to waste lines * Updating docs for YAML list of strings * Documentation for single and multiple targets --- DOCS.md | 43 +++++++++++++++++++++++++++++++++++++++++++ main.go | 47 +++++++++++++++++++++++++++-------------------- plugin.go | 17 ++++++++++++----- 3 files changed, 82 insertions(+), 25 deletions(-) diff --git a/DOCS.md b/DOCS.md index c6d2870..8f0ed90 100644 --- a/DOCS.md +++ b/DOCS.md @@ -124,6 +124,49 @@ pipeline: root_dir: some/path/here ``` +## Targets +You may want to only target a specific list of resources within your terraform code. To achieve this you can specify the `targets` parameter. If left undefined all resources will be planned/applied against as the default behavior. + +Single target: + +```yaml +pipeline: + terraform: + image: jmccann/drone-terraform:0.5 + plan: false + targets: aws_security_group.generic_sg + remote: + backend: S3 + config: + bucket: my-terraform-config-bucket + key: tf-states/my-project + region: us-east-1 + vars: + app_name: my-project + app_version: 1.0.0 +``` + +Multiple targets: + +```yaml +pipeline: + terraform: + image: jmccann/drone-terraform:0.5 + plan: false + targets: + - aws_security_group.generic_sg + - aws_security_group.app_sg + remote: + backend: S3 + config: + bucket: my-terraform-config-bucket + key: tf-states/my-project + region: us-east-1 + vars: + app_name: my-project + app_version: 1.0.0 +``` + ## Parallelism You may want to limit the number of concurrent operations as Terraform walks its graph. If you want to change Terraform's default parallelism (currently equal to 10) then set the `parallelism` parameter. diff --git a/main.go b/main.go index 49c4586..d80a411 100644 --- a/main.go +++ b/main.go @@ -4,8 +4,8 @@ import ( "encoding/json" "os" - "github.com/joho/godotenv" "github.com/Sirupsen/logrus" + "github.com/joho/godotenv" "github.com/urfave/cli" ) @@ -24,55 +24,61 @@ func main() { // cli.BoolFlag{ - Name: "plan", - Usage: "calculates a plan but does NOT apply it", + Name: "plan", + Usage: "calculates a plan but does NOT apply it", EnvVar: "PLUGIN_PLAN", }, cli.StringFlag{ - Name: "remote", - Usage: "contains the configuration for the Terraform remote state tracking", + Name: "remote", + Usage: "contains the configuration for the Terraform remote state tracking", EnvVar: "PLUGIN_REMOTE", }, cli.StringFlag{ - Name: "vars", - Usage: "a map of variables to pass to the Terraform `plan` and `apply` commands. Each value is passed as a `=` option", + Name: "vars", + Usage: "a map of variables to pass to the Terraform `plan` and `apply` commands. Each value is passed as a `=` option", EnvVar: "PLUGIN_VARS", }, cli.StringFlag{ - Name: "secrets", - Usage: "a map of secrets to pass to the Terraform `plan` and `apply` commands. Each value is passed as a `=` option", + Name: "secrets", + Usage: "a map of secrets to pass to the Terraform `plan` and `apply` commands. Each value is passed as a `=` option", EnvVar: "PLUGIN_SECRETS", }, cli.StringFlag{ - Name: "ca_cert", - Usage: "ca cert to add to your environment to allow terraform to use internal/private resources", + Name: "ca_cert", + Usage: "ca cert to add to your environment to allow terraform to use internal/private resources", EnvVar: "PLUGIN_CA_CERT", }, cli.BoolFlag{ - Name: "sensitive", - Usage: "whether or not to suppress terraform commands to stdout", + Name: "sensitive", + Usage: "whether or not to suppress terraform commands to stdout", EnvVar: "PLUGIN_SENSITIVE", }, cli.StringFlag{ - Name: "role_arn_to_assume", - Usage: "A role to assume before running the terraform commands", + Name: "role_arn_to_assume", + Usage: "A role to assume before running the terraform commands", EnvVar: "PLUGIN_ROLE_ARN_TO_ASSUME", }, cli.StringFlag{ - Name: "root_dir", - Usage: "The root directory where the terraform files live. When unset, the top level directory will be assumed", + Name: "root_dir", + Usage: "The root directory where the terraform files live. When unset, the top level directory will be assumed", EnvVar: "PLUGIN_ROOT_DIR", }, cli.IntFlag{ - Name: "parallelism", - Usage: "The number of concurrent operations as Terraform walks its graph", + Name: "parallelism", + Usage: "The number of concurrent operations as Terraform walks its graph", EnvVar: "PLUGIN_PARALLELISM", }, cli.StringFlag{ - Name: "env-file", + Name: "env-file", Usage: "source env file", }, + + cli.StringSliceFlag{ + Name: "targets", + Usage: "targets to run apply or plan on", + EnvVar: "PLUGIN_TARGETS", + }, } if err := app.Run(os.Args); err != nil { @@ -116,6 +122,7 @@ func run(c *cli.Context) error { RoleARN: c.String("role_arn_to_assume"), RootDir: c.String("root_dir"), Parallelism: c.Int("parallelism"), + Targets: c.StringSlice("targets"), }, } diff --git a/plugin.go b/plugin.go index 7a8adba..818b291 100644 --- a/plugin.go +++ b/plugin.go @@ -2,11 +2,11 @@ package main import ( "fmt" + "github.com/Sirupsen/logrus" "github.com/aws/aws-sdk-go/aws/credentials" "github.com/aws/aws-sdk-go/aws/credentials/stscreds" "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/sts" - "github.com/Sirupsen/logrus" "io/ioutil" "os" "os/exec" @@ -25,6 +25,7 @@ type ( RoleARN string RootDir string Parallelism int + Targets []string } Remote struct { @@ -52,9 +53,9 @@ func (p Plugin) Exec() error { commands = append(commands, remoteConfigCommand(remote)) } commands = append(commands, getModules()) - commands = append(commands, planCommand(p.Config.Vars, p.Config.Secrets, p.Config.Parallelism)) + commands = append(commands, planCommand(p.Config.Vars, p.Config.Secrets, p.Config.Parallelism, p.Config.Targets)) if !p.Config.Plan { - commands = append(commands, applyCommand(p.Config.Parallelism)) + commands = append(commands, applyCommand(p.Config.Parallelism, p.Config.Targets)) } commands = append(commands, deleteCache()) @@ -123,11 +124,14 @@ func getModules() *exec.Cmd { ) } -func planCommand(variables map[string]string, secrets map[string]string, parallelism int) *exec.Cmd { +func planCommand(variables map[string]string, secrets map[string]string, parallelism int, targets []string) *exec.Cmd { args := []string{ "plan", "-out=plan.tfout", } + for _, v := range targets { + args = append(args, "--target", fmt.Sprintf("%s", v)) + } for k, v := range variables { args = append(args, "-var") args = append(args, fmt.Sprintf("%s=%s", k, v)) @@ -145,10 +149,13 @@ func planCommand(variables map[string]string, secrets map[string]string, paralle ) } -func applyCommand(parallelism int) *exec.Cmd { +func applyCommand(parallelism int, targets []string) *exec.Cmd { args := []string{ "apply", } + for _, v := range targets { + args = append(args, "--target", fmt.Sprintf("%s", v)) + } if parallelism > 0 { args = append(args, fmt.Sprintf("-parallelism=%d", parallelism)) }