Browse Source

Merge pull request #94 from caioquirino/parallel_execution

Added support for parallel execution
pull/102/head
Jacob McCann 5 years ago
committed by GitHub
parent
commit
6a001c6029
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 16
      DOCS.md
  2. 6
      main.go
  3. 29
      plugin.go
  4. 38
      plugin_test.go

16
DOCS.md

@ -196,6 +196,19 @@ pipeline:
+ check: true
```
You may want to run some executions in parallel without having racing condition problems with the .terraform dir and
plan's output file.
```diff
pipeline:
backend-service:
image: jmccann/drone-terraform:<version>
+ tf_data_dir: .backend-service.terraform
frontend-service:
image: jmccann/drone-terraform:<version>
+ tf_data_dir: .frontend-service.terraform
```
# Parameter Reference
actions
@ -253,3 +266,6 @@ root_dir
parallelism
: The number of concurrent operations as Terraform walks its graph.
tf_data_dir
: changes the location where Terraform keeps its per-working-directory data, such as the current remote backend configuration.

6
main.go

@ -108,6 +108,11 @@ func main() {
Usage: "a list of var files to use. Each value is passed as -var-file=<value>",
EnvVar: "PLUGIN_VAR_FILES",
},
cli.StringFlag{
Name: "tf_data_dir",
Usage: "changes the location where Terraform keeps its per-working-directory data, such as the current remote backend configuration",
EnvVar: "PLUGIN_TF_DATA_DIR",
},
}
if err := app.Run(os.Args); err != nil {
@ -156,6 +161,7 @@ func run(c *cli.Context) error {
Parallelism: c.Int("parallelism"),
Targets: c.StringSlice("targets"),
VarFiles: c.StringSlice("var_files"),
TerraformDataDir: c.String("tf_data_dir"),
},
Netrc: Netrc{
Login: c.String("netrc.username"),

29
plugin.go

@ -33,6 +33,7 @@ type (
Parallelism int
Targets []string
VarFiles []string
TerraformDataDir string
}
// Netrc is credentials for cloning
@ -86,6 +87,12 @@ func (p Plugin) Exec() error {
return err
}
var terraformDataDir string = ".terraform"
if p.Config.TerraformDataDir != "" {
terraformDataDir = p.Config.TerraformDataDir
os.Setenv("TF_DATA_DIR", p.Config.TerraformDataDir)
}
var commands []*exec.Cmd
commands = append(commands, exec.Command("terraform", "version"))
@ -96,7 +103,7 @@ func (p Plugin) Exec() error {
commands = append(commands, installCaCert(p.Config.Cacert))
}
commands = append(commands, deleteCache())
commands = append(commands, deleteCache(terraformDataDir))
commands = append(commands, initCommand(p.Config.InitOptions))
commands = append(commands, getModules())
@ -120,7 +127,7 @@ func (p Plugin) Exec() error {
}
}
commands = append(commands, deleteCache())
commands = append(commands, deleteCache(terraformDataDir))
for _, c := range commands {
if c.Dir == "" {
@ -183,11 +190,11 @@ func assumeRole(roleArn string) {
os.Setenv("AWS_SESSION_TOKEN", value.SessionToken)
}
func deleteCache() *exec.Cmd {
func deleteCache(terraformDataDir string) *exec.Cmd {
return exec.Command(
"rm",
"-rf",
".terraform",
terraformDataDir,
)
}
@ -253,7 +260,8 @@ func tfApply(config Config) *exec.Cmd {
if config.InitOptions.LockTimeout != "" {
args = append(args, fmt.Sprintf("-lock-timeout=%s", config.InitOptions.LockTimeout))
}
args = append(args, "plan.tfout")
args = append(args, getTfoutPath())
return exec.Command(
"terraform",
args...,
@ -293,7 +301,7 @@ func tfPlan(config Config, destroy bool) *exec.Cmd {
if destroy {
args = append(args, "-destroy")
} else {
args = append(args, "-out=plan.tfout")
args = append(args, fmt.Sprintf("-out=%s", getTfoutPath()))
}
for _, v := range config.Targets {
@ -354,6 +362,15 @@ func tfFmt(config Config) *exec.Cmd {
)
}
func getTfoutPath() string {
terraformDataDir := os.Getenv("TF_DATA_DIR")
if terraformDataDir == ".terraform" || terraformDataDir == "" {
return "plan.tfout"
} else {
return fmt.Sprintf("%s.plan.tfout", terraformDataDir)
}
}
func vars(vs map[string]string) []string {
var args []string
for k, v := range vs {

38
plugin_test.go

@ -204,4 +204,42 @@ func TestPlugin(t *testing.T) {
}
})
})
g.Describe("tfDataDir", func() {
g.It("Should override the terraform data dir environment variable when provided", func() {
type args struct {
config Config
}
tests := []struct {
name string
args args
want *exec.Cmd
}{
{
"with TerraformDataDir",
args{config: Config{TerraformDataDir: ".overriden_terraform_dir"}},
exec.Command("terraform", "apply", ".overriden_terraform_dir.plan.tfout"),
},
{
"with TerraformDataDir value as .terraform",
args{config: Config{TerraformDataDir: ".terraform"}},
exec.Command("terraform", "apply", "plan.tfout"),
},
{
"without TerraformDataDir",
args{config: Config{}},
exec.Command("terraform", "apply", "plan.tfout"),
},
}
for _, tt := range tests {
os.Setenv("TF_DATA_DIR", tt.args.config.TerraformDataDir)
applied := tfApply(tt.args.config)
g.Assert(applied).Equal(tt.want)
}
})
})
}

Loading…
Cancel
Save