github.com/hazelops/ize@v1.1.12-0.20230915191306-97d7c0e48f11/internal/commands/terraform.go (about) 1 package commands 2 3 import ( 4 "fmt" 5 "github.com/hazelops/ize/internal/requirements" 6 "os" 7 8 "github.com/hazelops/ize/internal/config" 9 "github.com/hazelops/ize/internal/terraform" 10 "github.com/hazelops/ize/pkg/templates" 11 "github.com/sirupsen/logrus" 12 "github.com/spf13/cobra" 13 ) 14 15 type TerraformOptions struct { 16 Config *config.Project 17 Version string 18 Command []string 19 Local bool 20 } 21 22 var terraformLongDesc = templates.LongDesc(` 23 Run terraform command via terraform docker container. 24 By default, terraform runs locally. 25 At the same time, terraform will be downloaded and launched from ~/.ize/versions/terraform/ 26 27 To use a docker terraform, set value of "docker" to the --prefer-runtime global flag. 28 `) 29 30 var terraformExample = templates.Examples(` 31 # Run terraform init 32 ize -e dev -p default -r us-east-1 -n hazelops terraform --version 1.0.10 init -input=true 33 34 # Run terraform plan via config file 35 ize --config-file (or -c) /path/to/config terraform plan -out=$(ENV_DIR)/.terraform/tfplan -input=false 36 37 # Run terraform init via config file installed from env 38 export IZE_CONFIG_FILE=/path/to/config 39 ize terraform init -input=true 40 41 # Run terraform in docker 42 ize -e dev -p default -r us-east-1 -n hazelops --prefer-runtime=docker terraform --version 1.0.10 init -input=true 43 `) 44 45 func NewTerraformFlags(project *config.Project) *TerraformOptions { 46 return &TerraformOptions{ 47 Config: project, 48 } 49 } 50 51 func NewCmdTerraform(project *config.Project) *cobra.Command { 52 o := NewTerraformFlags(project) 53 54 cmd := &cobra.Command{ 55 Use: "terraform [flags] <terraform command> [terraform flags]", 56 Short: "Run terraform", 57 Long: terraformLongDesc, 58 Example: terraformExample, 59 DisableFlagParsing: true, 60 DisableFlagsInUseLine: true, 61 RunE: func(cmd *cobra.Command, args []string) error { 62 cmd.SilenceUsage = true 63 err := o.Complete() 64 if err != nil { 65 return err 66 } 67 68 err = o.Validate() 69 if err != nil { 70 return err 71 } 72 73 err = o.Run(args) 74 if err != nil { 75 return err 76 } 77 78 return nil 79 }, 80 } 81 82 return cmd 83 } 84 85 func (o *TerraformOptions) Complete() error { 86 if err := requirements.CheckRequirements(requirements.WithIzeStructure(), requirements.WithConfigFile()); err != nil { 87 return err 88 } 89 90 return nil 91 } 92 93 func (o *TerraformOptions) Validate() error { 94 if len(o.Config.Env) == 0 { 95 return fmt.Errorf("env must be specified\n") 96 } 97 return nil 98 } 99 100 func (o *TerraformOptions) Run(args []string) error { 101 var tf terraform.Terraform 102 103 v, err := o.Config.Session.Config.Credentials.Get() 104 if err != nil { 105 return fmt.Errorf("can't set AWS credentials: %w", err) 106 } 107 108 env := []string{ 109 fmt.Sprintf("ENV=%v", o.Config.Env), 110 fmt.Sprintf("USER=%v", os.Getenv("USER")), 111 fmt.Sprintf("AWS_PROFILE=%v", o.Config.AwsProfile), 112 fmt.Sprintf("TF_LOG=%v", o.Config.TFLog), 113 fmt.Sprintf("TF_LOG_PATH=%v", o.Config.TFLogPath), 114 fmt.Sprintf("AWS_ACCESS_KEY_ID=%v", v.AccessKeyID), 115 fmt.Sprintf("AWS_SECRET_ACCESS_KEY=%v", v.SecretAccessKey), 116 fmt.Sprintf("AWS_SESSION_TOKEN=%v", v.SessionToken), 117 } 118 119 if o.Config.Terraform != nil { 120 o.Version = o.Config.Terraform["infra"].Version 121 } 122 123 if o.Version == "" { 124 o.Version = o.Config.TerraformVersion 125 } 126 127 switch o.Config.PreferRuntime { 128 case "docker": 129 tf = terraform.NewDockerTerraform("infra", args, env, nil, o.Config) 130 case "native": 131 tf = terraform.NewLocalTerraform("infra", args, env, nil, o.Config) 132 err = tf.Prepare() 133 if err != nil { 134 return err 135 } 136 default: 137 return fmt.Errorf("can't supported %s runtime", o.Config.PreferRuntime) 138 } 139 140 logrus.Debug("starting terraform") 141 142 err = tf.Run() 143 if err != nil { 144 return err 145 } 146 147 return nil 148 }