If running apply-all in a subdirectory, but encountering templates with dependencies that are up a directory, it asks if I want to apply the external dependeny as well. But it asks it with an inverted prompt, such that answering 'n' causes apply to occur, and answering 'y' causes it to be skipped. I doubt, in the history of software development, that anyone has ever thought it intuitive to answer 'no' to make changes and 'yes' to cancel.
Even worse, if there are lots of such dependencies, you may have to hit the same answer many times, and then the final prompt asks whether I am sure I want to do it, this time expecting me to answer 'y' to make the change and 'n' to stop. And, of course if I am busily typing 'n', 'return', 'n', 'return', ... over and over again, it is all too likely that I will accidentally type 'n' to that final prompt, when what I actually want is 'y'. This is the very definition of poor user experience - inconsistent, repetitive, and difficult to visually parse. The prompts are so damn wordy, it can be hard to see exactly what module it is referring to as the string in question moves around from prompt to prompt.
And why does it prompt me over and over again for whether I want to run the same external dependencies. I already said 'no' 3 times (asking it to be run), so must I really answer 'no' a fourth time, too? How about just prompting me once, no matter how many of the apply-all targets have the same external dependency? It only seems to run apply on the external dependency once, so it clearly understands that things are supposed to be idempotent and it only needs to prompt me once, but nevertheless, it prompts me as many times as there are edges in the graph connecting to it. It would be a whole lot easier to type the correct number of 'n' respnses before typing 'y' if I didn't have 30-50 prompts for the same template every time.
Finally, how about some help text or documentation of apply-all so I can find out if there is a flag which will skip all of that prompting? I searched and searched, tried 'terragrunt apply-all help' which just starts prompting me, and 'terragrunt help apply-all' just says there is no help for apply-all. I found nothing in the terragrunt docs themselves. I'd really prefer to be able to run apply-all in my services directory without having to answer a prompt about each external dependency for each service. Ideally, a flag which just blanket accepts or denies all external dependencies would be really useful. As would documentation telling me what that flag is.
Did you try --help?
And --terragrunt-non-interactive (see CLI options)?
terragrunt-non-interactive says, in --help, that it answers 'y' to all
prompts. But I want it to answer 'n' to the first umpteen prompts because
they are asked from an inverted perspective - answer 'no' to do the default
thing, and 'yes' to do the non-default thing of skipping that dependency.
I want to NOT skip the dependencies, so I have to answer 'no' a whole bunch
of times, then answer 'yes' only to the very last prompt, which is
basically "are you sure you want to do all of that?". So
terragrunt-non-interactive isn't very useful until the prompts for doing an
action are inverted to a more 'normal' response pattern.
Module
/Users/sgendler/src/stem/yyyyyyy/xxxxxxxxxxx/us-east-1/stg/services/api
depends on module
/Users/sgendler/src/stem/yyyyyyyy/xxxxxxxxxxxxx/us-east-1/stg/vpc, which is
an external dependency outside of the current working directory. Should
Terragrunt skip over this external dependency? Warning, if you say 'no',
Terragrunt will make changes in
/Users/sgendler/src/stem/yyyyyyy/xxxxxxxxxxxxx/us-east-1/stg/vpc as well!
(y/n)
Note that the 'y' answer will skip the dependency, which seems an odd
default, and 'n' will make changes, which is what I want. I can't think of
any other software system I've encountered which prompts you to say y to
skip a step rather than saying 'y' to run a step. It's very
counterintuitive and could easily lead to failing to run apply in
dependencies if someone doesn't read the (very long) prompt text carefully.
Ideally, there should be a separate flag for setting the default response
for prompts about external dependencies than for the other prompts that
might be encountered, so that I can skip or process upper directory
dependencies whether I am using non-interactive mode or not.
Also, while I am at it - for some reason, init-all errors out if I run it
in a directory that doesn't have a terraform.tfvars file in it, even though
apply-all works just fine from the same directory - the subdirs all contain
terraform.tfvars files even though the directory I'm running the command
within does not. As a result, I have to manually run around to each
directory and do terragrunt init, just in case it is a dependency of
something I am going to run apply-all against, then I can go to a
subdirectory and do apply-all just to do all of the things in that subtree
(and their upper level dependencies). Otherwise, I run into problems where
some of the dependencies haven't been init'ed. Actually, it was even more
nefarious than that, because in many cases, it failed to recognize that it
needed to be init'ed despite having really old code stored locally, so I
actually had to do 'terragrunt init --terragrunt-source-update' (without a
--terragrunt-source flag) in order to update the locally stored copy of
templates that are referred via git rather than via terragrunt-source. It
took me a really long time to work out why terragrunt suddenly started
running out-of-date templates when I switched from using terragrunt-source
to the git reference stored in the tfvars file.
On Sat, May 5, 2018 at 6:40 AM, Yevgeniy Brikman notifications@github.com
wrote:
Did you try --help?
And --terragrunt-non-interactive (see CLI options
https://github.com/gruntwork-io/terragrunt#cli-options)?—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
https://github.com/gruntwork-io/terragrunt/issues/471#issuecomment-386806475,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AdYOqMGu7GGIVwr8jPQh8mUdPtcJy-i8ks5tvavcgaJpZM4Ty7sP
.
This is the "easy" fix that makes terragrunt *-all --terragrunt-non-interactive work as expected.
diff --git a/configstack/module.go b/configstack/module.go
index 37ad025..e3f9bf2 100644
--- a/configstack/module.go
+++ b/configstack/module.go
@@ -197,12 +197,12 @@ func resolveExternalDependenciesForModules(moduleMap map[string]*TerraformModule
continue
}
- alreadyApplied, err := confirmExternalDependencyAlreadyApplied(module, externalDependency, terragruntOptions)
+ shouldApply, err := confirmShouldApplyExternalDependency(module, externalDependency, terragruntOptions)
if err != nil {
return externalDependencies, err
}
- externalDependency.AssumeAlreadyApplied = alreadyApplied
+ externalDependency.AssumeAlreadyApplied = !shouldApply
allExternalDependencies[externalDependency.Path] = externalDependency
}
}
@@ -247,8 +247,8 @@ func resolveExternalDependenciesForModule(module *TerraformModule, moduleMap map
// Confirm with the user whether they want Terragrunt to assume the given dependency of the given module is already
// applied. If the user selects "no", then Terragrunt will apply that module as well.
-func confirmExternalDependencyAlreadyApplied(module *TerraformModule, dependency *TerraformModule, terragruntOptions *options.TerragruntOptions) (bool, error) {
- prompt := fmt.Sprintf("Module %s depends on module %s, which is an external dependency outside of the current working directory. Should Terragrunt skip over this external dependency? Warning, if you say 'no', Terragrunt will make changes in %s as well!", module.Path, dependency.Path, dependency.Path)
+func confirmShouldApplyExternalDependency(module *TerraformModule, dependency *TerraformModule, terragruntOptions *options.TerragruntOptions) (bool, error) {
+ prompt := fmt.Sprintf("Module %s depends on module %s, which is an external dependency outside of the current working directory. Should Terragrunt run this external dependency? Warning, if you say 'yes', Terragrunt will make changes in %s as well!", module.Path, dependency.Path, dependency.Path)
return shell.PromptUserForYesNo(prompt, terragruntOptions)
}
The problem is that this is a breaking change of sort because it flips the behavior that some people may be used to.
@natefaerber Does --terragrunt-non-interactive still work properly with your change?
In terms of backwards compatibility, is the only change that you would now enter "yes" to indicate "run xxx on this dependency too" rather than "no"?
Yes and Yes. I haven't done a full suite of tests with --terragrunt-non-interactive but it seems to be working as expected with my plan-all. I guess I should test the case without the flag and make sure the yes and no answers do what is expected. I can get back to you on this.
I agree that it's more intuitive to answer "yes" for these, so, despite the backwards incompatibility, I'd welcome this PR! Thanks 👍
Fixed by #497. Thx @natefaerber!