github.com/sinangedik/terraform@v0.3.5/command/refresh.go (about) 1 package command 2 3 import ( 4 "fmt" 5 "log" 6 "os" 7 "strings" 8 9 "github.com/hashicorp/terraform/remote" 10 ) 11 12 // RefreshCommand is a cli.Command implementation that refreshes the state 13 // file. 14 type RefreshCommand struct { 15 Meta 16 } 17 18 func (c *RefreshCommand) Run(args []string) int { 19 args = c.Meta.process(args, true) 20 21 cmdFlags := c.Meta.flagSet("refresh") 22 cmdFlags.StringVar(&c.Meta.statePath, "state", DefaultStateFilename, "path") 23 cmdFlags.StringVar(&c.Meta.stateOutPath, "state-out", "", "path") 24 cmdFlags.StringVar(&c.Meta.backupPath, "backup", "", "path") 25 cmdFlags.Usage = func() { c.Ui.Error(c.Help()) } 26 if err := cmdFlags.Parse(args); err != nil { 27 return 1 28 } 29 30 var configPath string 31 args = cmdFlags.Args() 32 if len(args) > 1 { 33 c.Ui.Error("The apply command expacts at most one argument.") 34 cmdFlags.Usage() 35 return 1 36 } else if len(args) == 1 { 37 configPath = args[0] 38 } else { 39 var err error 40 configPath, err = os.Getwd() 41 if err != nil { 42 c.Ui.Error(fmt.Sprintf("Error getting pwd: %s", err)) 43 } 44 } 45 46 // Check if remote state is enabled 47 remoteEnabled, err := remote.HaveLocalState() 48 if err != nil { 49 c.Ui.Error(fmt.Sprintf("Failed to check for remote state: %v", err)) 50 return 1 51 } 52 53 // Verify that the state path exists. The "ContextArg" function below 54 // will actually do this, but we want to provide a richer error message 55 // if possible. 56 if !remoteEnabled { 57 if _, err := os.Stat(c.Meta.statePath); err != nil { 58 if os.IsNotExist(err) { 59 c.Ui.Error(fmt.Sprintf( 60 "The Terraform state file for your infrastructure does not\n"+ 61 "exist. The 'refresh' command only works and only makes sense\n"+ 62 "when there is existing state that Terraform is managing. Please\n"+ 63 "double-check the value given below and try again. If you\n"+ 64 "haven't created infrastructure with Terraform yet, use the\n"+ 65 "'terraform apply' command.\n\n"+ 66 "Path: %s", 67 c.Meta.statePath)) 68 return 1 69 } 70 71 c.Ui.Error(fmt.Sprintf( 72 "There was an error reading the Terraform state that is needed\n"+ 73 "for refreshing. The path and error are shown below.\n\n"+ 74 "Path: %s\n\nError: %s", 75 c.Meta.statePath, 76 err)) 77 return 1 78 } 79 } 80 81 // Build the context based on the arguments given 82 ctx, _, err := c.Context(contextOpts{ 83 Path: configPath, 84 StatePath: c.Meta.statePath, 85 }) 86 if err != nil { 87 c.Ui.Error(err.Error()) 88 return 1 89 } 90 if !validateContext(ctx, c.Ui) { 91 return 1 92 } 93 if err := ctx.Input(c.InputMode()); err != nil { 94 c.Ui.Error(fmt.Sprintf("Error configuring: %s", err)) 95 return 1 96 } 97 98 state, err := ctx.Refresh() 99 if err != nil { 100 c.Ui.Error(fmt.Sprintf("Error refreshing state: %s", err)) 101 return 1 102 } 103 104 log.Printf("[INFO] Writing state output to: %s", c.Meta.StateOutPath()) 105 if err := c.Meta.PersistState(state); err != nil { 106 c.Ui.Error(fmt.Sprintf("Error writing state file: %s", err)) 107 return 1 108 } 109 110 return 0 111 } 112 113 func (c *RefreshCommand) Help() string { 114 helpText := ` 115 Usage: terraform refresh [options] [dir] 116 117 Update the state file of your infrastructure with metadata that matches 118 the physical resources they are tracking. 119 120 This will not modify your infrastructure, but it can modify your 121 state file to update metadata. This metadata might cause new changes 122 to occur when you generate a plan or call apply next. 123 124 Options: 125 126 -backup=path Path to backup the existing state file before 127 modifying. Defaults to the "-state-out" path with 128 ".backup" extension. Set to "-" to disable backup. 129 130 -input=true Ask for input for variables if not directly set. 131 132 -no-color If specified, output won't contain any color. 133 134 -state=path Path to read and save state (unless state-out 135 is specified). Defaults to "terraform.tfstate". 136 137 -state-out=path Path to write updated state file. By default, the 138 "-state" path will be used. 139 140 -var 'foo=bar' Set a variable in the Terraform configuration. This 141 flag can be set multiple times. 142 143 -var-file=foo Set variables in the Terraform configuration from 144 a file. If "terraform.tfvars" is present, it will be 145 automatically loaded if this flag is not specified. 146 147 ` 148 return strings.TrimSpace(helpText) 149 } 150 151 func (c *RefreshCommand) Synopsis() string { 152 return "Update local state file against real resources" 153 }