You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
164 lines
3.4 KiB
164 lines
3.4 KiB
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"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"
|
|
"io/ioutil"
|
|
"os"
|
|
"os/exec"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
var (
|
|
buildCommit string
|
|
)
|
|
|
|
type terraform struct {
|
|
Remote remote `json:"remote"`
|
|
Plan bool `json:"plan"`
|
|
Vars map[string]string `json:"vars"`
|
|
Cacert string `json:"ca_cert"`
|
|
Sensitive bool `json:"sensitive"`
|
|
RoleARN string `json:"role_arn_to_assume"`
|
|
RootDir string `json:"root_dir"`
|
|
}
|
|
|
|
type remote struct {
|
|
Backend string `json:"backend"`
|
|
Config map[string]string `json:"config"`
|
|
}
|
|
|
|
func main() {
|
|
fmt.Printf("Drone Terraform Plugin built from %s\n", buildCommit)
|
|
|
|
workspace := plugin.Workspace{}
|
|
vargs := terraform{}
|
|
|
|
plugin.Param("workspace", &workspace)
|
|
plugin.Param("vargs", &vargs)
|
|
plugin.MustParse()
|
|
|
|
if vargs.RoleARN != "" {
|
|
assumeRole(vargs.RoleARN)
|
|
}
|
|
|
|
var commands []*exec.Cmd
|
|
remote := vargs.Remote
|
|
if vargs.Cacert != "" {
|
|
commands = append(commands, installCaCert(vargs.Cacert))
|
|
}
|
|
if remote.Backend != "" {
|
|
commands = append(commands, deleteCache())
|
|
commands = append(commands, remoteConfigCommand(remote))
|
|
}
|
|
commands = append(commands, planCommand(vargs.Vars))
|
|
if !vargs.Plan {
|
|
commands = append(commands, applyCommand())
|
|
}
|
|
commands = append(commands, deleteCache())
|
|
|
|
for _, c := range commands {
|
|
c.Env = os.Environ()
|
|
c.Dir = workspace.Path
|
|
if vargs.RootDir != "" {
|
|
c.Dir = c.Dir + "/" + vargs.RootDir
|
|
}
|
|
c.Stdout = os.Stdout
|
|
c.Stderr = os.Stderr
|
|
if !vargs.Sensitive {
|
|
trace(c)
|
|
}
|
|
|
|
err := c.Run()
|
|
if err != nil {
|
|
fmt.Println("Error!")
|
|
fmt.Println(err)
|
|
os.Exit(1)
|
|
}
|
|
fmt.Println("Command completed successfully")
|
|
}
|
|
|
|
}
|
|
|
|
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",
|
|
)
|
|
}
|
|
|
|
func deleteCache() *exec.Cmd {
|
|
return exec.Command(
|
|
"rm",
|
|
"-rf",
|
|
".terraform",
|
|
)
|
|
}
|
|
|
|
func remoteConfigCommand(config remote) *exec.Cmd {
|
|
args := []string{
|
|
"remote",
|
|
"config",
|
|
fmt.Sprintf("-backend=%s", config.Backend),
|
|
}
|
|
for k, v := range config.Config {
|
|
args = append(args, fmt.Sprintf("-backend-config=%s=%s", k, v))
|
|
}
|
|
return exec.Command(
|
|
"terraform",
|
|
args...,
|
|
)
|
|
}
|
|
|
|
func planCommand(variables map[string]string) *exec.Cmd {
|
|
args := []string{
|
|
"plan",
|
|
"-out=plan.tfout",
|
|
}
|
|
for k, v := range variables {
|
|
args = append(args, "-var")
|
|
args = append(args, fmt.Sprintf("%s=%s", k, v))
|
|
}
|
|
return exec.Command(
|
|
"terraform",
|
|
args...,
|
|
)
|
|
}
|
|
|
|
func applyCommand() *exec.Cmd {
|
|
return exec.Command(
|
|
"terraform",
|
|
"apply",
|
|
"plan.tfout",
|
|
)
|
|
}
|
|
|
|
func assumeRole(roleArn string) {
|
|
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()
|
|
if err != nil {
|
|
fmt.Println("Error assuming role!")
|
|
fmt.Println(err)
|
|
os.Exit(1)
|
|
}
|
|
os.Setenv("AWS_ACCESS_KEY_ID", value.AccessKeyID)
|
|
os.Setenv("AWS_SECRET_ACCESS_KEY", value.SecretAccessKey)
|
|
os.Setenv("AWS_SESSION_TOKEN", value.SessionToken)
|
|
}
|
|
|
|
func trace(cmd *exec.Cmd) {
|
|
fmt.Println("$", strings.Join(cmd.Args, " "))
|
|
}
|
|
|