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