Summary
Running --bootstrap with -a shell aborts with component: unbound variable
under set -u, because component is only declared in the non-bootstrap branch
but the shell action references it bare at
bin/terraform.sh:936.
Root Cause
set -uo pipefail is enabled at bin/terraform.sh:8.
component is declared readonly only in the non-bootstrap branch:
bin/terraform.sh:316-326
if [ "${bootstrap}" == 'true' ]; then
[ -n "${component_arg}" ] \
&& error_and_die 'The --bootstrap parameter and the -c/--component parameter are mutually exclusive';
...
else
[ -n "${component_arg}" ] \
|| error_and_die 'Required argument missing: -c/--component';
readonly component="${component_arg}"; # only set here
...
fi;
In bootstrap mode, -c is explicitly rejected, so component is intentionally
never set. But the shell action prints it bare:
bin/terraform.sh:936
echo -e "Here's a shell for the ${component} component. ...";
Under set -u, this aborts before the shell is ever launched.
This is the same root-cause class as #50 (bootstrap-mode reference to a variable
that is only declared in the non-bootstrap branch) — there it was
${environment}, here it is ${component}.
Evidence
Minimal reproduction of the mechanism (mirrors the conditional declaration then
a bootstrap-mode bare reference):
$ bash -c 'set -uo pipefail
bootstrap="true"; component_arg=""
[ "${bootstrap}" == "true" ] || readonly component="${component_arg}"
echo "before component use"
echo "component is ${component}"'
before component use
bash: line 1: component: unbound variable
# exit code 127
Expected: either a working shell for the bootstrap component, or a clear
error_and_die explaining that shell is not supported with --bootstrap.
Actual: aborts with component: unbound variable.
Reproduction Steps
bin/terraform.sh \
-p myproject \
-r eu-west-2 \
--bootstrap \
-a shell \
-- -input=false
(The -- -input=false is required only to work around #49.) With valid AWS
credentials the run proceeds to the shell case and aborts at
bin/terraform.sh:936 with
line 936: component: unbound variable.
Suggested Fix
This is a niche path, so the fixer should decide the intended semantics:
- Preferred — make the message tolerant of bootstrap mode. Use
${component:-bootstrap} (or ${component_name}, which is set by
bin/terraform.sh:443 to basename of the component
path and equals bootstrap in bootstrap mode) in the line-936 message, so a
bootstrap shell works.
- Or explicitly reject it. If a shell into the bootstrap component is not a
supported workflow, add an early error_and_die when
bootstrap == 'true' && action == 'shell'.
Note that ${component_name} is already the safe, always-set equivalent used
elsewhere (e.g. the backend filename at
bin/terraform.sh:680), so switching the message to it
is low-risk.
Affected Platforms
All platforms and all bash versions (verified on bash 5.1.16).
Related
Summary
Running
--bootstrapwith-a shellaborts withcomponent: unbound variableunder
set -u, becausecomponentis only declared in the non-bootstrap branchbut the
shellaction references it bare atbin/terraform.sh:936.
Root Cause
set -uo pipefailis enabled at bin/terraform.sh:8.componentis declaredreadonlyonly in the non-bootstrap branch:bin/terraform.sh:316-326
In bootstrap mode,
-cis explicitly rejected, socomponentis intentionallynever set. But the
shellaction prints it bare:bin/terraform.sh:936
Under
set -u, this aborts before the shell is ever launched.This is the same root-cause class as #50 (bootstrap-mode reference to a variable
that is only declared in the non-bootstrap branch) — there it was
${environment}, here it is${component}.Evidence
Minimal reproduction of the mechanism (mirrors the conditional declaration then
a bootstrap-mode bare reference):
Expected: either a working shell for the bootstrap component, or a clear
error_and_dieexplaining thatshellis not supported with--bootstrap.Actual: aborts with
component: unbound variable.Reproduction Steps
(The
-- -input=falseis required only to work around #49.) With valid AWScredentials the run proceeds to the
shellcase and aborts atbin/terraform.sh:936 with
line 936: component: unbound variable.Suggested Fix
This is a niche path, so the fixer should decide the intended semantics:
${component:-bootstrap}(or${component_name}, which is set bybin/terraform.sh:443 to
basenameof the componentpath and equals
bootstrapin bootstrap mode) in the line-936 message, so abootstrap shell works.
supported workflow, add an early
error_and_diewhenbootstrap == 'true' && action == 'shell'.Note that
${component_name}is already the safe, always-set equivalent usedelsewhere (e.g. the backend filename at
bin/terraform.sh:680), so switching the message to it
is low-risk.
Affected Platforms
All platforms and all bash versions (verified on bash 5.1.16).
Related
${environment}unset in bootstrap mode).set -uregressions from the v2.3.0 hardening. All fourare best addressed together as a single "complete the
set -uhardening"pass.