Skip to content

Instantly share code, notes, and snippets.

@jackishere
Created November 12, 2023 17:52
Show Gist options
  • Save jackishere/b5b34cee9e099c28545771ad72361794 to your computer and use it in GitHub Desktop.
Save jackishere/b5b34cee9e099c28545771ad72361794 to your computer and use it in GitHub Desktop.
My first real go cli
package main
import (
"context"
"flag"
"log"
"os"
"github.com/hashicorp/go-version"
"github.com/hashicorp/hc-install/product"
"github.com/hashicorp/hc-install/releases"
"github.com/hashicorp/terraform-exec/tfexec"
)
const (
TERRAFORM_VERSION = "1.6.3"
AWS_ACCOUNT_ID = "123456789012"
AWS_REGION = "us-east-2"
)
type command struct {
command_name string
deployment_id string
module_name string
module_version string
env_name string
cloud_name string
}
var cmd command
func init() {
cmd = command{}
flag.StringVar(&cmd.command_name, "command_name", "apply", "Enter command name")
flag.StringVar(&cmd.deployment_id, "deployment_id", "1", "Enter deployment id")
flag.StringVar(&cmd.module_name, "module_name", "bucket", "Enter module name")
flag.StringVar(&cmd.module_version, "module_version", "0.0.2", "Enter module version")
flag.StringVar(&cmd.env_name, "env_name", "dev", "Enter env version")
flag.StringVar(&cmd.cloud_name, "cloud_name", "aws|123456789012|us-east-2", "Enter Cloud name")
flag.Parse()
log.Printf("cmd: %+v", cmd)
}
func copyModule(module_name, module_version, destinationFolder string) error {
const BASE_MODULES_PATH = "/Users/jack/repos/platform9/modules"
sourceFilePath := BASE_MODULES_PATH + "/" + module_name + "/" + module_version + "/all.tf"
destinationFilePath := destinationFolder + "/all.tf"
// Read the content of the source file
content, err := os.ReadFile(sourceFilePath)
if err != nil {
log.Println("Error reading source file:", err)
return err
}
// Write the content to the destination file
err = os.WriteFile(destinationFilePath, content, 0644)
if err != nil {
log.Println("Error writing to destination file:", err)
return err
}
log.Printf("File copied from %s to %s\n", sourceFilePath, destinationFilePath)
return nil
}
func main() {
log.Println("Started")
log.Println("Create temp dir..")
tempDir, err := os.MkdirTemp("", "tf-")
if err != nil {
log.Println("Error creating temporary directory:", err)
return
}
log.Println("Temporary directory created:", tempDir)
log.Println("Copy module..")
err = copyModule(cmd.module_name, cmd.module_version, tempDir)
if err != nil {
log.Println("Error copy module:", err)
return
}
//Installer
installer := &releases.ExactVersion{
Product: product.Terraform,
Version: version.Must(version.NewVersion(TERRAFORM_VERSION)),
}
log.Printf("installer: %+v", installer)
//Install tf executable
log.Println("Install..")
execPath, err := installer.Install(context.Background())
if err != nil {
log.Fatalf("error installing Terraform: %s", err)
}
log.Printf("execPath: %+v", execPath)
// build tfexec struct instance
log.Println("Instantiating..")
tf, err := tfexec.NewTerraform(tempDir, execPath)
if err != nil {
log.Fatalf("error running NewTerraform: %s", err)
}
log.Printf("tf: %+v", tf)
// tf.SetStdout(os.Stdout)
tf.SetStderr(os.Stderr)
//Init
log.Println("Init..")
initOpts := []tfexec.InitOption{
tfexec.BackendConfig("bucket=" + AWS_ACCOUNT_ID + "-terraform-states"),
tfexec.BackendConfig("key=" + cmd.deployment_id + ".terraform.tfstate"),
}
err = tf.Init(context.Background(), initOpts...)
if err != nil {
log.Fatalf("error running Init: %s", err)
}
//Apply
if cmd.command_name == "apply" {
log.Println("Apply..")
applyOpts := []tfexec.ApplyOption{
tfexec.Var("module_name=" + cmd.module_name),
tfexec.Var("module_version=" + cmd.module_version),
tfexec.Var("env_name=" + cmd.env_name),
tfexec.Var("aws_region=" + AWS_REGION),
}
err = tf.Apply(context.Background(), applyOpts...)
if err != nil {
log.Fatalf("error running Apply: %s", err)
}
}
//Destroy
if cmd.command_name == "destroy" {
log.Println("Destroy..")
destroyOpts := []tfexec.DestroyOption{
tfexec.Var("module_name=" + cmd.module_name),
tfexec.Var("module_version=" + cmd.module_version),
tfexec.Var("env_name=" + cmd.env_name),
tfexec.Var("aws_region=" + AWS_REGION),
}
err = tf.Destroy(context.Background(), destroyOpts...)
if err != nil {
log.Fatalf("error running Destroy: %s", err)
}
}
log.Println("Ended")
}
2023/11/12 19:47:10 cmd: {command_name:apply deployment_id:1 module_name:bucket module_version:0.0.2 env_name:dev cloud_name:aws|259390106611|us-east-2}
2023/11/12 19:47:10 Started
2023/11/12 19:47:10 Create temp dir..
2023/11/12 19:47:10 Temporary directory created: /var/folders/j0/nqjj590516gbpfj47vbsf7x40000gn/T/tf-2360331273
2023/11/12 19:47:10 Copy module..
2023/11/12 19:47:10 File copied from /Users/jack/repos/platform9/modules/bucket/0.0.2/all.tf to /var/folders/j0/nqjj590516gbpfj47vbsf7x40000gn/T/tf-2360331273/all.tf
2023/11/12 19:47:10 installer: &{Product:{Name:terraform BinaryName:0x102cfa430 GetVersion:0x102cfa440 BuildInstructions:0x1031bca80} Version:1.6.3 InstallDir: Timeout:0s Enterprise:<nil> SkipChecksumVerification:false ArmoredPublicKey: apiBaseURL: logger:<nil> pathsToRemove:[]}
2023/11/12 19:47:10 Install..
2023/11/12 19:47:13 execPath: /var/folders/j0/nqjj590516gbpfj47vbsf7x40000gn/T/terraform_1775984559/terraform
2023/11/12 19:47:13 Instantiating..
2023/11/12 19:47:13 tf: &{execPath:/var/folders/j0/nqjj590516gbpfj47vbsf7x40000gn/T/terraform_1775984559/terraform workingDir:/var/folders/j0/nqjj590516gbpfj47vbsf7x40000gn/T/tf-2360331273 appendUserAgent: disablePluginTLS:false skipProviderVerify:false env:map[] stdout:<nil> stderr:<nil> logger:0x14000136900 log: logCore: logPath: logProvider: versionLock:{state:0 sema:0} execVersion:<nil> provVersions:map[]}
2023/11/12 19:47:13 Init..
2023/11/12 19:47:28 Apply..
2023/11/12 19:47:40 Ended
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment