command: "terraform apply" uses interactive confirmation by default
In the 0.10 release we added an opt-in mode where Terraform would prompt interactively for confirmation during apply. We made this opt-in to give those who wrap Terraform in automation some time to update their scripts to explicitly opt out of this behavior where appropriate. Here we switch the default so that a "terraform apply" with no arguments will -- if it computes a non-empty diff -- display the diff and wait for the user to type "yes" in similar vein to the "terraform destroy" command. This makes the commonly-used "terraform apply" a safe workflow for interactive use, so "terraform plan" is now mainly for use in automation where a separate planning step is used. The apply command remains non-interactive when given an explicit plan file. The previous behavior -- though not recommended -- can be obtained by explicitly setting the -auto-approve option on the apply command line, and indeed that is how all of the tests are updated here so that they can continue to run non-interactively.
This commit is contained in:
parent
0265b1c0fe
commit
400038eda4
|
@ -47,7 +47,7 @@ func (c *ApplyCommand) Run(args []string) int {
|
|||
}
|
||||
cmdFlags.BoolVar(&refresh, "refresh", true, "refresh")
|
||||
if !c.Destroy {
|
||||
cmdFlags.BoolVar(&autoApprove, "auto-approve", true, "skip interactive approval of plan before applying")
|
||||
cmdFlags.BoolVar(&autoApprove, "auto-approve", false, "skip interactive approval of plan before applying")
|
||||
}
|
||||
cmdFlags.IntVar(
|
||||
&c.Meta.parallelism, "parallelism", DefaultParallelism, "parallelism")
|
||||
|
@ -119,11 +119,6 @@ func (c *ApplyCommand) Run(args []string) int {
|
|||
if plan != nil {
|
||||
// Reset the config path for backend loading
|
||||
configPath = ""
|
||||
|
||||
if !autoApprove {
|
||||
c.Ui.Error("Cannot combine -auto-approve=false with a plan file.")
|
||||
return 1
|
||||
}
|
||||
}
|
||||
|
||||
// Load the module if we don't have one yet (not running from plan)
|
||||
|
@ -253,12 +248,6 @@ Usage: terraform apply [options] [DIR-OR-PLAN]
|
|||
configuration or an execution plan can be provided. Execution plans can be
|
||||
used to only execute a pre-determined set of actions.
|
||||
|
||||
DIR can also be a SOURCE as given to the "init" command. In this case,
|
||||
apply behaves as though "init" was called followed by "apply". This only
|
||||
works for sources that aren't files, and only if the current working
|
||||
directory is empty of Terraform files. This is a shortcut for getting
|
||||
started.
|
||||
|
||||
Options:
|
||||
|
||||
-backup=path Path to backup the existing state file before
|
||||
|
@ -269,9 +258,7 @@ Options:
|
|||
|
||||
-lock-timeout=0s Duration to retry a state lock.
|
||||
|
||||
-auto-approve=true Skip interactive approval of plan before applying. In a
|
||||
future version of Terraform, this flag's default value
|
||||
will change to false.
|
||||
-auto-approve Skip interactive approval of plan before applying.
|
||||
|
||||
-input=true Ask for input for variables if not directly set.
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@ func TestApply(t *testing.T) {
|
|||
|
||||
args := []string{
|
||||
"-state", statePath,
|
||||
"-auto-approve",
|
||||
testFixturePath("apply"),
|
||||
}
|
||||
if code := c.Run(args); code != 0 {
|
||||
|
@ -72,6 +73,7 @@ func TestApply_lockedState(t *testing.T) {
|
|||
|
||||
args := []string{
|
||||
"-state", statePath,
|
||||
"-auto-approve",
|
||||
testFixturePath("apply"),
|
||||
}
|
||||
if code := c.Run(args); code == 0 {
|
||||
|
@ -113,6 +115,7 @@ func TestApply_lockedStateWait(t *testing.T) {
|
|||
args := []string{
|
||||
"-state", statePath,
|
||||
"-lock-timeout", "4s",
|
||||
"-auto-approve",
|
||||
testFixturePath("apply"),
|
||||
}
|
||||
if code := c.Run(args); code != 0 {
|
||||
|
@ -186,6 +189,7 @@ func TestApply_parallelism(t *testing.T) {
|
|||
|
||||
args := []string{
|
||||
"-state", statePath,
|
||||
"-auto-approve",
|
||||
fmt.Sprintf("-parallelism=%d", par),
|
||||
testFixturePath("parallelism"),
|
||||
}
|
||||
|
@ -239,6 +243,7 @@ func TestApply_configInvalid(t *testing.T) {
|
|||
|
||||
args := []string{
|
||||
"-state", testTempFile(t),
|
||||
"-auto-approve",
|
||||
testFixturePath("apply-config-invalid"),
|
||||
}
|
||||
if code := c.Run(args); code != 1 {
|
||||
|
@ -281,6 +286,7 @@ func TestApply_defaultState(t *testing.T) {
|
|||
serial := localState.State().Serial
|
||||
|
||||
args := []string{
|
||||
"-auto-approve",
|
||||
testFixturePath("apply"),
|
||||
}
|
||||
if code := c.Run(args); code != 0 {
|
||||
|
@ -344,6 +350,7 @@ func TestApply_error(t *testing.T) {
|
|||
|
||||
args := []string{
|
||||
"-state", statePath,
|
||||
"-auto-approve",
|
||||
testFixturePath("apply-error"),
|
||||
}
|
||||
if code := c.Run(args); code != 1 {
|
||||
|
@ -385,6 +392,7 @@ func TestApply_input(t *testing.T) {
|
|||
|
||||
args := []string{
|
||||
"-state", statePath,
|
||||
"-auto-approve",
|
||||
testFixturePath("apply-input"),
|
||||
}
|
||||
if code := c.Run(args); code != 0 {
|
||||
|
@ -420,6 +428,7 @@ func TestApply_inputPartial(t *testing.T) {
|
|||
|
||||
args := []string{
|
||||
"-state", statePath,
|
||||
"-auto-approve",
|
||||
"-var", "foo=foovalue",
|
||||
testFixturePath("apply-input-partial"),
|
||||
}
|
||||
|
@ -460,6 +469,7 @@ func TestApply_noArgs(t *testing.T) {
|
|||
|
||||
args := []string{
|
||||
"-state", statePath,
|
||||
"-auto-approve",
|
||||
}
|
||||
if code := c.Run(args); code != 0 {
|
||||
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
|
||||
|
@ -783,6 +793,7 @@ func TestApply_refresh(t *testing.T) {
|
|||
|
||||
args := []string{
|
||||
"-state", statePath,
|
||||
"-auto-approve",
|
||||
testFixturePath("apply"),
|
||||
}
|
||||
if code := c.Run(args); code != 0 {
|
||||
|
@ -875,6 +886,7 @@ func TestApply_shutdown(t *testing.T) {
|
|||
|
||||
args := []string{
|
||||
"-state", statePath,
|
||||
"-auto-approve",
|
||||
testFixturePath("apply-shutdown"),
|
||||
}
|
||||
if code := c.Run(args); code != 0 {
|
||||
|
@ -934,6 +946,7 @@ func TestApply_state(t *testing.T) {
|
|||
// Run the apply command pointing to our existing state
|
||||
args := []string{
|
||||
"-state", statePath,
|
||||
"-auto-approve",
|
||||
testFixturePath("apply"),
|
||||
}
|
||||
if code := c.Run(args); code != 0 {
|
||||
|
@ -1008,6 +1021,7 @@ func TestApply_sensitiveOutput(t *testing.T) {
|
|||
|
||||
args := []string{
|
||||
"-state", statePath,
|
||||
"-auto-approve",
|
||||
testFixturePath("apply-sensitive-output"),
|
||||
}
|
||||
|
||||
|
@ -1040,6 +1054,7 @@ func TestApply_stateFuture(t *testing.T) {
|
|||
|
||||
args := []string{
|
||||
"-state", statePath,
|
||||
"-auto-approve",
|
||||
testFixturePath("apply"),
|
||||
}
|
||||
if code := c.Run(args); code == 0 {
|
||||
|
@ -1071,6 +1086,7 @@ func TestApply_statePast(t *testing.T) {
|
|||
|
||||
args := []string{
|
||||
"-state", statePath,
|
||||
"-auto-approve",
|
||||
testFixturePath("apply"),
|
||||
}
|
||||
if code := c.Run(args); code != 0 {
|
||||
|
@ -1103,6 +1119,7 @@ func TestApply_vars(t *testing.T) {
|
|||
}
|
||||
|
||||
args := []string{
|
||||
"-auto-approve",
|
||||
"-var", "foo=bar",
|
||||
"-state", statePath,
|
||||
testFixturePath("apply-vars"),
|
||||
|
@ -1146,6 +1163,7 @@ func TestApply_varFile(t *testing.T) {
|
|||
}
|
||||
|
||||
args := []string{
|
||||
"-auto-approve",
|
||||
"-var-file", varFilePath,
|
||||
"-state", statePath,
|
||||
testFixturePath("apply-vars"),
|
||||
|
@ -1199,6 +1217,7 @@ func TestApply_varFileDefault(t *testing.T) {
|
|||
}
|
||||
|
||||
args := []string{
|
||||
"-auto-approve",
|
||||
"-state", statePath,
|
||||
testFixturePath("apply-vars"),
|
||||
}
|
||||
|
@ -1251,6 +1270,7 @@ func TestApply_varFileDefaultJSON(t *testing.T) {
|
|||
}
|
||||
|
||||
args := []string{
|
||||
"-auto-approve",
|
||||
"-state", statePath,
|
||||
testFixturePath("apply-vars"),
|
||||
}
|
||||
|
@ -1303,6 +1323,7 @@ func TestApply_backup(t *testing.T) {
|
|||
|
||||
// Run the apply command pointing to our existing state
|
||||
args := []string{
|
||||
"-auto-approve",
|
||||
"-state", statePath,
|
||||
"-backup", backupPath,
|
||||
testFixturePath("apply"),
|
||||
|
@ -1353,6 +1374,7 @@ func TestApply_disableBackup(t *testing.T) {
|
|||
|
||||
// Run the apply command pointing to our existing state
|
||||
args := []string{
|
||||
"-auto-approve",
|
||||
"-state", statePath,
|
||||
"-backup", "-",
|
||||
testFixturePath("apply"),
|
||||
|
@ -1411,6 +1433,7 @@ func TestApply_terraformEnv(t *testing.T) {
|
|||
}
|
||||
|
||||
args := []string{
|
||||
"-auto-approve",
|
||||
"-state", statePath,
|
||||
testFixturePath("apply-terraform-env"),
|
||||
}
|
||||
|
@ -1466,6 +1489,7 @@ func TestApply_terraformEnvNonDefault(t *testing.T) {
|
|||
}
|
||||
|
||||
args := []string{
|
||||
"-auto-approve",
|
||||
testFixturePath("apply-terraform-env"),
|
||||
}
|
||||
if code := c.Run(args); code != 0 {
|
||||
|
|
|
@ -149,7 +149,7 @@ func TestAutoApplyInAutomation(t *testing.T) {
|
|||
}
|
||||
|
||||
//// APPLY
|
||||
stdout, stderr, err = tf.Run("apply", "-input=false", "-auto-approve=true")
|
||||
stdout, stderr, err = tf.Run("apply", "-input=false", "-auto-approve")
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected apply error: %s\nstderr:\n%s", err, stderr)
|
||||
}
|
||||
|
|
|
@ -18,13 +18,9 @@ Usage: `terraform apply [options] [dir-or-plan]`
|
|||
|
||||
By default, `apply` scans the current directory for the configuration
|
||||
and applies the changes appropriately. However, a path to another configuration
|
||||
or an execution plan can be provided. Execution plans can be used to only
|
||||
execute a pre-determined set of actions.
|
||||
|
||||
The `dir` argument can also be a [module source](/docs/modules/index.html).
|
||||
In this case, `apply` behaves as though `init` were called with that
|
||||
argument followed by an `apply` in the current directory. This is meant
|
||||
as a shortcut for getting started.
|
||||
or an execution plan can be provided. Explicit execution plans files can be
|
||||
used to split plan and apply into separate steps within
|
||||
[automation systems](/guides/running-terraform-in-automation.html).
|
||||
|
||||
The command-line flags are all optional. The list of available flags are:
|
||||
|
||||
|
@ -37,8 +33,7 @@ The command-line flags are all optional. The list of available flags are:
|
|||
|
||||
* `-input=true` - Ask for input for variables if not directly set.
|
||||
|
||||
* `-auto-approve=true` - Skip interactive approval of plan before applying. In a
|
||||
future version of Terraform, this flag's default value will change to false.
|
||||
* `-auto-approve` - Skip interactive approval of plan before applying.
|
||||
|
||||
* `-no-color` - Disables output with coloring.
|
||||
|
||||
|
|
|
@ -11,8 +11,17 @@ description: |-
|
|||
The `terraform plan` command is used to create an execution plan. Terraform
|
||||
performs a refresh, unless explicitly disabled, and then determines what
|
||||
actions are necessary to achieve the desired state specified in the
|
||||
configuration files. The plan can be saved using `-out`, and then provided
|
||||
to `terraform apply` to ensure only the pre-planned actions are executed.
|
||||
configuration files.
|
||||
|
||||
This command is a convenient way to check whether the execution plan for a
|
||||
set of changes matches your expectations without making any changes to
|
||||
real resources or to the state. For example, `terraform plan` might be run
|
||||
before committing a change to version control, to create confidence that it
|
||||
will behave as expected.
|
||||
|
||||
The optional `-out` argument can be used to save the generated plan to a file
|
||||
for later execution with `terraform apply`, which can be useful when
|
||||
[running Terraform in automation](/guides/running-terraform-in-automation.html).
|
||||
|
||||
## Usage
|
||||
|
||||
|
|
|
@ -174,15 +174,15 @@ Where manual approval is not required, a simpler sequence of commands
|
|||
can be used:
|
||||
|
||||
* `terraform init -input=false`
|
||||
* `terraform apply -input=false -auto-approve=true`
|
||||
* `terraform apply -input=false -auto-approve`
|
||||
|
||||
This variant of the `apply` command implicitly creates a new plan and then
|
||||
immediately applies it. The `-auto-approve=true` option tells Terraform not
|
||||
immediately applies it. The `-auto-approve` option tells Terraform not
|
||||
to require interactive approval of the plan before applying it.
|
||||
|
||||
~> When Terraform is empowered to make destructive changes to infrastructure,
|
||||
manual review of plans is always recommended unless downtime is tolerated
|
||||
in the event of unintended changes. Use automatic apply **only** with
|
||||
in the event of unintended changes. Use automatic approval **only** with
|
||||
non-critical infrastructure.
|
||||
|
||||
## Testing Pull Requests with `terraform plan`
|
||||
|
|
|
@ -165,16 +165,19 @@ specifying that version in configuration to ensure that running
|
|||
is not necessary for following the getting started guide, since this
|
||||
configuration will be discarded at the end.
|
||||
|
||||
## Execution Plan
|
||||
## Apply Changes
|
||||
|
||||
Next, let's see what Terraform would do if we asked it to
|
||||
apply this configuration. In the same directory as the
|
||||
`example.tf` file you created, run `terraform plan`. You
|
||||
should see output similar to what is copied below. We've
|
||||
truncated some of the output to save space.
|
||||
~> **Note:** The commands shown in this guide apply to Terraform 0.11 and
|
||||
above. Earlier versions require using the `terraform plan` command to
|
||||
see the execution plan before applying it. Use `terraform version`
|
||||
to confirm your running version.
|
||||
|
||||
In the same directory as the `example.tf` file you created, run
|
||||
`terraform apply`. You should see output similar to below, though we've
|
||||
truncated some of the output to save space:
|
||||
|
||||
```
|
||||
$ terraform plan
|
||||
$ terraform apply
|
||||
# ...
|
||||
|
||||
+ aws_instance.example
|
||||
|
@ -198,30 +201,31 @@ $ terraform plan
|
|||
vpc_security_group_ids.#: "<computed>"
|
||||
```
|
||||
|
||||
`terraform plan` shows what changes Terraform will apply to
|
||||
your infrastructure given the current state of your infrastructure
|
||||
as well as the current contents of your configuration.
|
||||
|
||||
If `terraform plan` failed with an error, read the error message
|
||||
and fix the error that occurred. At this stage, it is probably a
|
||||
syntax error in the configuration.
|
||||
|
||||
This output shows the _execution plan_, describing which actions Terraform
|
||||
will take in order to change real infrastructure to match the configuration.
|
||||
The output format is similar to the diff format generated by tools
|
||||
such as Git. The output has a "+" next to "aws\_instance.example",
|
||||
such as Git. The output has a `+` next to `aws_instance.example`,
|
||||
meaning that Terraform will create this resource. Beneath that,
|
||||
it shows the attributes that will be set. When the value displayed
|
||||
is `<computed>`, it means that the value won't be known
|
||||
until the resource is created.
|
||||
|
||||
## Apply
|
||||
|
||||
The plan looks good, our configuration appears valid, so it's time to
|
||||
create real resources. Run `terraform apply` in the same directory
|
||||
as your `example.tf`, and watch it go! It will take a few minutes
|
||||
since Terraform waits for the EC2 instance to become available.
|
||||
If `terraform apply` failed with an error, read the error message
|
||||
and fix the error that occurred. At this stage, it is likely to be a
|
||||
syntax error in the configuration.
|
||||
|
||||
If the plan was created successfully, Terraform will now pause and wait for
|
||||
approval before proceeding. If anything in the plan seems incorrect or
|
||||
dangerous, it is safe to abort here with no changes made to your infrastructure.
|
||||
In this case the plan looks acceptable, so type `yes` at the confirmation
|
||||
prompt to proceed.
|
||||
|
||||
Executing the plan will take a few minutes since Terraform waits for the EC2
|
||||
instance to become available:
|
||||
|
||||
```
|
||||
$ terraform apply
|
||||
# ...
|
||||
aws_instance.example: Creating...
|
||||
ami: "" => "ami-2757f631"
|
||||
instance_type: "" => "t2.micro"
|
||||
|
@ -235,20 +239,19 @@ Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
|
|||
# ...
|
||||
```
|
||||
|
||||
Done! You can go to the AWS console to prove to yourself that the
|
||||
EC2 instance has been created.
|
||||
After this, Terraform is all done! You can go to the EC2 console to see the
|
||||
created EC2 instance. (Make sure you're looking at the same region that was
|
||||
configured in the provider configuration!)
|
||||
|
||||
Terraform also puts some state into the `terraform.tfstate` file
|
||||
by default. This state file is extremely important; it maps various
|
||||
resource metadata to actual resource IDs so that Terraform knows
|
||||
what it is managing. This file must be saved and distributed
|
||||
to anyone who might run Terraform. It is generally recommended to
|
||||
Terraform also wrote some data into the `terraform.tfstate` file. This state
|
||||
file is extremely important; it keeps track of the IDs of created resources
|
||||
so that Terraform knows what it is managing. This file must be saved and
|
||||
distributed to anyone who might run Terraform. It is generally recommended to
|
||||
[setup remote state](https://www.terraform.io/docs/state/remote.html)
|
||||
when working with Terraform. This will mean that any potential secrets
|
||||
stored in the state file, will not be checked into version control
|
||||
when working with Terraform, to share the state automatically, but this is
|
||||
not necessary for simple situations like this Getting Started guide.
|
||||
|
||||
|
||||
You can inspect the state using `terraform show`:
|
||||
You can inspect the current state using `terraform show`:
|
||||
|
||||
```
|
||||
$ terraform show
|
||||
|
@ -267,8 +270,8 @@ aws_instance.example:
|
|||
```
|
||||
|
||||
You can see that by creating our resource, we've also gathered
|
||||
a lot more metadata about it. This metadata can actually be referenced
|
||||
for other resources or outputs, which will be covered later in
|
||||
a lot of information about it. These values can actually be referenced
|
||||
to configure other resources or outputs, which will be covered later in
|
||||
the getting started guide.
|
||||
|
||||
## Provisioning
|
||||
|
@ -279,8 +282,7 @@ an image-based infrastructure (perhaps creating images with
|
|||
[Packer](https://www.packer.io)), then this is all you need.
|
||||
|
||||
However, many infrastructures still require some sort of initialization
|
||||
or software provisioning step. Terraform supports
|
||||
provisioners,
|
||||
or software provisioning step. Terraform supports provisioners,
|
||||
which we'll cover a little bit later in the getting started guide,
|
||||
in order to do this.
|
||||
|
||||
|
|
|
@ -40,12 +40,13 @@ an Ubuntu 16.10 AMI. Terraform configurations are meant to be
|
|||
changed like this. You can also completely remove resources
|
||||
and Terraform will know to destroy the old one.
|
||||
|
||||
## Execution Plan
|
||||
## Apply Changes
|
||||
|
||||
Let's see what Terraform will do with the change we made.
|
||||
After changing the configuration, run `terraform apply` again to see how
|
||||
Terraform will apply this change to the existing resources.
|
||||
|
||||
```
|
||||
$ terraform plan
|
||||
$ terraform apply
|
||||
# ...
|
||||
|
||||
-/+ aws_instance.example
|
||||
|
@ -63,25 +64,23 @@ $ terraform plan
|
|||
vpc_security_group_ids.#: "1" => "<computed>"
|
||||
```
|
||||
|
||||
The prefix "-/+" means that Terraform will destroy and recreate
|
||||
the resource, versus purely updating it in-place. While some attributes
|
||||
can do in-place updates (which are shown with a "~" prefix), AMI
|
||||
changing on EC2 instance requires a new resource. Terraform handles
|
||||
these details for you, and the execution plan makes it clear what
|
||||
Terraform will do.
|
||||
The prefix `-/+` means that Terraform will destroy and recreate
|
||||
the resource, rather than updating it in-place. While some attributes
|
||||
can be updated in-place (which are shown with the `~` prefix), changing the
|
||||
AMI for an EC2 instance requires recreating it. Terraform handles these details
|
||||
for you, and the execution plan makes it clear what Terraform will do.
|
||||
|
||||
Additionally, the plan output shows that the AMI change is what
|
||||
necessitated the creation of a new resource. Using this information,
|
||||
you can tweak your changes to possibly avoid destroy/create updates
|
||||
if you didn't want to do them at this time.
|
||||
Additionally, the execution plan shows that the AMI change is what
|
||||
required resource to be replaced. Using this information,
|
||||
you can adjust your changes to possibly avoid destroy/create updates
|
||||
if they are not acceptable in some situations.
|
||||
|
||||
## Apply
|
||||
Once again, Terraform prompts for approval of the execution plan before
|
||||
proceeding. Answer `yes` to execute the planned steps:
|
||||
|
||||
From the plan, we know what will happen. Let's apply and enact
|
||||
the change.
|
||||
|
||||
```
|
||||
$ terraform apply
|
||||
# ...
|
||||
aws_instance.example: Refreshing state... (ID: i-64c268fe)
|
||||
aws_instance.example: Destroying...
|
||||
aws_instance.example: Destruction complete
|
||||
|
@ -113,9 +112,9 @@ Apply complete! Resources: 1 added, 0 changed, 1 destroyed.
|
|||
# ...
|
||||
```
|
||||
|
||||
As the plan predicted, Terraform started by destroying our old
|
||||
instance, then creating the new one. You can use `terraform show`
|
||||
again to see the new properties associated with this instance.
|
||||
As indicated by the execution plan, Terraform first destroyed the existing
|
||||
instance and then created a new one in its place. You can use `terraform show`
|
||||
again to see the new values associated with this instance.
|
||||
|
||||
## Next
|
||||
|
||||
|
|
|
@ -52,13 +52,13 @@ The syntax for this interpolation should be straightforward:
|
|||
it requests the "id" attribute from the "aws\_instance.example"
|
||||
resource.
|
||||
|
||||
## Plan and Execute
|
||||
## Apply Changes
|
||||
|
||||
Run `terraform plan` to view the execution plan. The output
|
||||
will look something like the following:
|
||||
Run `terraform apply` to see how Terraform plans to apply this change.
|
||||
The output will look similar to the following:
|
||||
|
||||
```
|
||||
$ terraform plan
|
||||
$ terraform apply
|
||||
|
||||
+ aws_eip.ip
|
||||
allocation_id: "<computed>"
|
||||
|
@ -96,11 +96,12 @@ raw interpolation is still present. This is because this variable
|
|||
won't be known until the "aws\_instance" is created. It will be
|
||||
replaced at apply-time.
|
||||
|
||||
Next, run `terraform apply`. The output will look similar to the
|
||||
As usual, Terraform prompts for confirmation before making any changes.
|
||||
Answer `yes` to apply. The continued output will look similar to the
|
||||
following:
|
||||
|
||||
```
|
||||
$ terraform apply
|
||||
# ...
|
||||
aws_instance.example: Creating...
|
||||
ami: "" => "ami-b374d5a5"
|
||||
instance_type: "" => "t2.micro"
|
||||
|
@ -120,12 +121,10 @@ aws_eip.ip: Creation complete
|
|||
Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
|
||||
```
|
||||
|
||||
It is clearer to see from actually running Terraform, but
|
||||
Terraform creates the EC2 instance before the elastic IP
|
||||
address. Due to the interpolation earlier where the elastic
|
||||
IP requires the ID of the EC2 instance, Terraform is able
|
||||
to infer a dependency, and knows to create the instance
|
||||
first.
|
||||
As shown above, Terraform created the EC2 instance before creating the Elastic
|
||||
IP address. Due to the interpolation expression that passes the ID of the EC2
|
||||
instance to the Elastic IP address, Terraform is able to infer a dependency,
|
||||
and knows it must create the instance first.
|
||||
|
||||
## Implicit and Explicit Dependencies
|
||||
|
||||
|
|
|
@ -18,29 +18,27 @@ environments. But if you're using Terraform to spin up multiple
|
|||
environments such as development, test, QA environments, then
|
||||
destroying is a useful action.
|
||||
|
||||
## Plan
|
||||
## Destroy
|
||||
|
||||
Before destroying our infrastructure, we can use the plan command
|
||||
to see what resources Terraform will destroy.
|
||||
Resources can be destroyed using the `terraform destroy` command, which is
|
||||
similar to `terraform apply` but it behaves as if all of the resources have
|
||||
been removed from the configuration.
|
||||
|
||||
```
|
||||
$ terraform plan -destroy
|
||||
$ terraform destroy
|
||||
# ...
|
||||
|
||||
- aws_instance.example
|
||||
```
|
||||
|
||||
With the `-destroy` flag, we're asking Terraform to plan a destroy,
|
||||
where all resources under Terraform management are destroyed. You can
|
||||
use this output to verify exactly what resources Terraform is managing
|
||||
and will destroy.
|
||||
The `-` prefix indicates that a the instance will be destroyed. As with apply,
|
||||
Terraform shows its execution plan and waits for approval before making any
|
||||
changes.
|
||||
|
||||
## Destroy
|
||||
|
||||
Let's destroy the infrastructure now:
|
||||
Answer `yes` to execute this plan and destroy the infrastructure:
|
||||
|
||||
```
|
||||
$ terraform destroy
|
||||
# ...
|
||||
aws_instance.example: Destroying...
|
||||
|
||||
Apply complete! Resources: 0 added, 0 changed, 1 destroyed.
|
||||
|
@ -48,15 +46,11 @@ Apply complete! Resources: 0 added, 0 changed, 1 destroyed.
|
|||
# ...
|
||||
```
|
||||
|
||||
The `terraform destroy` command should ask you to verify that you
|
||||
really want to destroy the infrastructure. Terraform only accepts the
|
||||
literal "yes" as an answer as a safety mechanism. Once entered, Terraform
|
||||
will go through and destroy the infrastructure.
|
||||
|
||||
Just like with `apply`, Terraform is smart enough to determine what order
|
||||
things should be destroyed. In our case, we only had one resource, so there
|
||||
wasn't any ordering necessary. But in more complicated cases with multiple
|
||||
resources, Terraform will destroy in the proper order.
|
||||
Just like with `apply`, Terraform determines the order in which
|
||||
things must be destroyed. In this case there was only one resource, so no
|
||||
ordering was necessary. In more complicated cases with multiple resources,
|
||||
Terraform will destroy them in a suitable order to respect dependencies,
|
||||
as we'll see later in this guide.
|
||||
|
||||
## Next
|
||||
|
||||
|
|
|
@ -89,10 +89,10 @@ updates.
|
|||
## Planning and Apply Modules
|
||||
|
||||
With the modules downloaded, we can now plan and apply it. If you run
|
||||
`terraform plan`, you should see output similar to below:
|
||||
`terraform apply`, you should see output similar to below:
|
||||
|
||||
```
|
||||
$ terraform plan
|
||||
$ terraform apply
|
||||
# ...
|
||||
+ module.consul.aws_instance.server.0
|
||||
# ...
|
||||
|
@ -106,18 +106,16 @@ $ terraform plan
|
|||
Plan: 4 to add, 0 to change, 0 to destroy.
|
||||
```
|
||||
|
||||
Conceptually, the module is treated like a black box. In the plan, however
|
||||
Conceptually, the module is treated like a black box. In the plan however,
|
||||
Terraform shows each resource the module manages so you can see each detail
|
||||
about what the plan will do. If you'd like compressed plan output, you can
|
||||
specify the `-module-depth=` flag to get Terraform to output summaries by
|
||||
module.
|
||||
about what actions the plan will take.
|
||||
|
||||
Next, run `terraform apply` to create the module. Note that as we warned above,
|
||||
As usual, Terraform waits for confirmation before making any changes. Answer
|
||||
`yes` to create the resources from the module. Note that, as we warned above,
|
||||
the resources this module creates are outside of the AWS free tier, so this
|
||||
will have some cost associated with it.
|
||||
|
||||
```
|
||||
$ terraform apply
|
||||
# ...
|
||||
Apply complete! Resources: 3 added, 0 changed, 0 destroyed.
|
||||
```
|
||||
|
|
|
@ -60,6 +60,8 @@ then run `apply`:
|
|||
|
||||
```
|
||||
$ terraform apply
|
||||
# ...
|
||||
|
||||
aws_instance.example: Creating...
|
||||
ami: "" => "ami-b374d5a5"
|
||||
instance_type: "" => "t2.micro"
|
||||
|
|
|
@ -66,11 +66,11 @@ configuring a backend, run `terraform init` to setup Terraform. It should
|
|||
ask if you want to migrate your state to Consul. Say "yes" and Terraform
|
||||
will copy your state.
|
||||
|
||||
Now, if you run `terraform plan`, Terraform should state that there are
|
||||
Now, if you run `terraform apply`, Terraform should state that there are
|
||||
no changes:
|
||||
|
||||
```
|
||||
$ terraform plan
|
||||
$ terraform apply
|
||||
# ...
|
||||
|
||||
No changes. Infrastructure is up-to-date.
|
||||
|
|
|
@ -66,7 +66,7 @@ You can set variables directly on the command-line with the
|
|||
accepts this flag, such as `apply`, `plan`, and `refresh`:
|
||||
|
||||
```
|
||||
$ terraform plan \
|
||||
$ terraform apply \
|
||||
-var 'access_key=foo' \
|
||||
-var 'secret_key=bar'
|
||||
# ...
|
||||
|
@ -100,7 +100,7 @@ You can use multiple `-var-file` arguments in a single command, with some
|
|||
checked in to version control and others not checked in. For example:
|
||||
|
||||
```
|
||||
$ terraform plan \
|
||||
$ terraform apply \
|
||||
-var-file="secret.tfvars" \
|
||||
-var-file="production.tfvars"
|
||||
```
|
||||
|
@ -116,10 +116,11 @@ List and map type variables must be populated via one of the other mechanisms.
|
|||
|
||||
#### UI Input
|
||||
|
||||
If you execute `terraform plan` or apply without doing anything,
|
||||
Terraform will ask you to input the variables interactively. These
|
||||
variables are not saved, but provides a nice user experience for getting
|
||||
started with Terraform.
|
||||
If you execute `terraform apply` with certain variables unspecified,
|
||||
Terraform will ask you to input their values interactively. These
|
||||
values are not saved, but this provides a convenient workflow when getting
|
||||
started with Terraform. UI Input is not recommended for everyday use of
|
||||
Terraform.
|
||||
|
||||
-> **Note**: UI Input is only supported for string variables. List and map
|
||||
variables must be populated via one of the other mechanisms.
|
||||
|
@ -199,7 +200,7 @@ We set defaults above, but maps can also be set using the `-var` and
|
|||
`-var-file` values. For example:
|
||||
|
||||
```
|
||||
$ terraform plan -var 'amis={ us-east-1 = "foo", us-west-2 = "bar" }'
|
||||
$ terraform apply -var 'amis={ us-east-1 = "foo", us-west-2 = "bar" }'
|
||||
# ...
|
||||
```
|
||||
|
||||
|
|
Loading…
Reference in New Issue