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  }