2015-11-09 19:23:42 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
2016-04-04 21:24:02 +00:00
|
|
|
"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/drone/drone-plugin-go/plugin"
|
2016-02-21 11:41:22 +00:00
|
|
|
"io/ioutil"
|
2015-11-09 19:23:42 +00:00
|
|
|
"os"
|
|
|
|
"os/exec"
|
|
|
|
"strings"
|
2016-04-04 21:24:02 +00:00
|
|
|
"time"
|
2015-11-09 19:23:42 +00:00
|
|
|
)
|
|
|
|
|
2016-02-21 11:41:22 +00:00
|
|
|
var (
|
|
|
|
buildCommit string
|
|
|
|
)
|
|
|
|
|
2015-11-10 01:07:05 +00:00
|
|
|
type terraform struct {
|
2016-02-11 18:07:08 +00:00
|
|
|
Remote remote `json:"remote"`
|
|
|
|
Plan bool `json:"plan"`
|
|
|
|
Vars map[string]string `json:"vars"`
|
|
|
|
Cacert string `json:"ca_cert"`
|
|
|
|
Sensitive bool `json:"sensitive"`
|
2016-04-04 21:24:02 +00:00
|
|
|
RoleARN string `json:"role_arn_to_assume"`
|
|
|
|
RootDir string `json:"root_dir"`
|
2015-11-10 01:07:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
type remote struct {
|
|
|
|
Backend string `json:"backend"`
|
|
|
|
Config map[string]string `json:"config"`
|
2015-11-09 19:23:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func main() {
|
2016-02-21 11:41:22 +00:00
|
|
|
fmt.Printf("Drone Terraform Plugin built from %s\n", buildCommit)
|
2015-11-09 19:23:42 +00:00
|
|
|
|
|
|
|
workspace := plugin.Workspace{}
|
2015-11-10 01:07:05 +00:00
|
|
|
vargs := terraform{}
|
2015-11-09 19:23:42 +00:00
|
|
|
|
|
|
|
plugin.Param("workspace", &workspace)
|
|
|
|
plugin.Param("vargs", &vargs)
|
|
|
|
plugin.MustParse()
|
|
|
|
|
2016-03-23 12:43:20 +00:00
|
|
|
if vargs.RoleARN != "" {
|
|
|
|
assumeRole(vargs.RoleARN)
|
|
|
|
}
|
|
|
|
|
2015-11-10 01:07:05 +00:00
|
|
|
var commands []*exec.Cmd
|
|
|
|
remote := vargs.Remote
|
2016-02-11 17:32:55 +00:00
|
|
|
if vargs.Cacert != "" {
|
|
|
|
commands = append(commands, installCaCert(vargs.Cacert))
|
2016-02-09 19:27:12 +00:00
|
|
|
}
|
2015-11-10 01:07:05 +00:00
|
|
|
if remote.Backend != "" {
|
2016-02-19 00:09:23 +00:00
|
|
|
commands = append(commands, deleteCache())
|
2015-11-10 01:07:05 +00:00
|
|
|
commands = append(commands, remoteConfigCommand(remote))
|
|
|
|
}
|
2016-04-04 21:21:41 +00:00
|
|
|
commands = append(commands, getModules())
|
2015-11-10 01:07:05 +00:00
|
|
|
commands = append(commands, planCommand(vargs.Vars))
|
2016-02-14 22:00:32 +00:00
|
|
|
if !vargs.Plan {
|
2015-11-10 01:07:05 +00:00
|
|
|
commands = append(commands, applyCommand())
|
2015-11-09 19:23:42 +00:00
|
|
|
}
|
2016-02-19 00:09:23 +00:00
|
|
|
commands = append(commands, deleteCache())
|
2015-11-09 19:23:42 +00:00
|
|
|
|
2015-11-10 01:07:05 +00:00
|
|
|
for _, c := range commands {
|
|
|
|
c.Env = os.Environ()
|
|
|
|
c.Dir = workspace.Path
|
2016-04-07 23:30:59 +00:00
|
|
|
if c.Dir == "" {
|
|
|
|
wd, err := os.Getwd()
|
|
|
|
if err == nil {
|
|
|
|
c.Dir = wd
|
|
|
|
}
|
|
|
|
}
|
2016-04-04 21:24:02 +00:00
|
|
|
if vargs.RootDir != "" {
|
|
|
|
c.Dir = c.Dir + "/" + vargs.RootDir
|
|
|
|
}
|
2015-11-10 01:07:05 +00:00
|
|
|
c.Stdout = os.Stdout
|
|
|
|
c.Stderr = os.Stderr
|
2016-02-11 18:07:08 +00:00
|
|
|
if !vargs.Sensitive {
|
|
|
|
trace(c)
|
|
|
|
}
|
2015-11-09 19:23:42 +00:00
|
|
|
|
2015-11-10 01:07:05 +00:00
|
|
|
err := c.Run()
|
2015-11-09 19:23:42 +00:00
|
|
|
if err != nil {
|
2015-11-10 13:56:18 +00:00
|
|
|
fmt.Println("Error!")
|
|
|
|
fmt.Println(err)
|
2015-11-09 19:23:42 +00:00
|
|
|
os.Exit(1)
|
|
|
|
}
|
2015-11-10 13:56:18 +00:00
|
|
|
fmt.Println("Command completed successfully")
|
2015-11-09 19:23:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2016-02-09 19:27:12 +00:00
|
|
|
func installCaCert(cacert string) *exec.Cmd {
|
|
|
|
ioutil.WriteFile("/usr/local/share/ca-certificates/ca_cert.crt", []byte(cacert), 0644)
|
|
|
|
return exec.Command(
|
|
|
|
"update-ca-certificates",
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2016-02-19 00:09:23 +00:00
|
|
|
func deleteCache() *exec.Cmd {
|
|
|
|
return exec.Command(
|
|
|
|
"rm",
|
|
|
|
"-rf",
|
|
|
|
".terraform",
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2015-11-10 01:07:05 +00:00
|
|
|
func remoteConfigCommand(config remote) *exec.Cmd {
|
|
|
|
args := []string{
|
|
|
|
"remote",
|
|
|
|
"config",
|
|
|
|
fmt.Sprintf("-backend=%s", config.Backend),
|
|
|
|
}
|
|
|
|
for k, v := range config.Config {
|
2015-11-10 02:44:38 +00:00
|
|
|
args = append(args, fmt.Sprintf("-backend-config=%s=%s", k, v))
|
2015-11-10 01:07:05 +00:00
|
|
|
}
|
|
|
|
return exec.Command(
|
|
|
|
"terraform",
|
|
|
|
args...,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2016-04-04 21:21:41 +00:00
|
|
|
func getModules() *exec.Cmd {
|
|
|
|
return exec.Command(
|
|
|
|
"terraform",
|
|
|
|
"get",
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2015-11-10 01:07:05 +00:00
|
|
|
func planCommand(variables map[string]string) *exec.Cmd {
|
|
|
|
args := []string{
|
|
|
|
"plan",
|
|
|
|
"-out=plan.tfout",
|
|
|
|
}
|
|
|
|
for k, v := range variables {
|
2015-11-10 02:44:38 +00:00
|
|
|
args = append(args, "-var")
|
|
|
|
args = append(args, fmt.Sprintf("%s=%s", k, v))
|
2015-11-10 01:07:05 +00:00
|
|
|
}
|
|
|
|
return exec.Command(
|
|
|
|
"terraform",
|
|
|
|
args...,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
func applyCommand() *exec.Cmd {
|
|
|
|
return exec.Command(
|
|
|
|
"terraform",
|
|
|
|
"apply",
|
|
|
|
"plan.tfout",
|
|
|
|
)
|
2015-11-09 19:23:42 +00:00
|
|
|
}
|
|
|
|
|
2016-03-23 12:43:20 +00:00
|
|
|
func assumeRole(roleArn string) {
|
2016-04-04 21:24:02 +00:00
|
|
|
client := sts.New(session.New())
|
|
|
|
duration := time.Hour * 1
|
|
|
|
stsProvider := &stscreds.AssumeRoleProvider{
|
|
|
|
Client: client,
|
|
|
|
Duration: duration,
|
|
|
|
RoleARN: roleArn,
|
|
|
|
RoleSessionName: "drone",
|
|
|
|
}
|
|
|
|
|
|
|
|
value, err := credentials.NewCredentials(stsProvider).Get()
|
2016-03-23 12:43:20 +00:00
|
|
|
if err != nil {
|
|
|
|
fmt.Println("Error assuming role!")
|
|
|
|
fmt.Println(err)
|
|
|
|
os.Exit(1)
|
|
|
|
}
|
2016-04-04 21:24:02 +00:00
|
|
|
os.Setenv("AWS_ACCESS_KEY_ID", value.AccessKeyID)
|
|
|
|
os.Setenv("AWS_SECRET_ACCESS_KEY", value.SecretAccessKey)
|
|
|
|
os.Setenv("AWS_SESSION_TOKEN", value.SessionToken)
|
2016-03-23 12:43:20 +00:00
|
|
|
}
|
|
|
|
|
2015-11-09 19:23:42 +00:00
|
|
|
func trace(cmd *exec.Cmd) {
|
|
|
|
fmt.Println("$", strings.Join(cmd.Args, " "))
|
|
|
|
}
|