Skip to content

Commit 7ae8646

Browse files
committed
Add option to search for secrets in remote state resources
Now by default, remote state resources will be excluded from the search for secrets unless specifically requested via the new --remote-state option.
1 parent 10e7067 commit 7ae8646

File tree

1 file changed

+32
-6
lines changed

1 file changed

+32
-6
lines changed

project_setup/scripts/terraform-to-secrets

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ Options:
4444
-l --log-level=LEVEL If specified, then the log level will be set to
4545
the specified value. Valid values are "debug", "info",
4646
"warning", "error", and "critical". [default: info]
47+
-m --remote-state Look for secrets in remote state resources also.
4748
-r --repo=REPONAME Use provided repository name instead of detecting it.
4849
-s --state=JSONFILE Read state from a file instead of asking Terraform.
4950
-t --token=PAT Specify a GitHub personal access token (PAT).
@@ -137,18 +138,27 @@ def find_tagged_secret(
137138
return
138139

139140

140-
def find_outputs(terraform_state: Dict) -> Generator[Dict, None, None]:
141+
def find_outputs(
142+
terraform_state: Dict, include_remote_state: bool
143+
) -> Generator[Dict, None, None]:
141144
"""Search for resources with outputs in the Terraform state."""
142145
for resource in terraform_state["values"]["root_module"].get("resources", []):
146+
# Exclude remote state resources unless requested
147+
if (
148+
not include_remote_state
149+
and resource.get("type") == "terraform_remote_state"
150+
):
151+
continue
143152
if resource.get("values", dict()).get("outputs", dict()):
144153
yield resource["values"]["outputs"]
145154

146155

147156
def parse_tagged_outputs(
148157
terraform_state: Dict,
158+
include_remote_state: bool,
149159
) -> Generator[Tuple[str, str], None, None]:
150160
"""Search all outputs for tags requesting the creation of a secret."""
151-
for outputs in find_outputs(terraform_state):
161+
for outputs in find_outputs(terraform_state, include_remote_state):
152162
for output_name, output_data in outputs.items():
153163
yield from find_tagged_secret(output_name, output_data)
154164
return
@@ -207,9 +217,16 @@ def parse_creds(terraform_state: Dict) -> Generator[Tuple[str, str, str], None,
207217

208218
def parse_tagged_resources(
209219
terraform_state: Dict,
220+
include_remote_state: bool,
210221
) -> Generator[Tuple[str, str], None, None]:
211222
"""Search all resources for tags requesting the creation of a secret."""
212223
for resource in find_resources(terraform_state, None):
224+
# Exclude remote state resources unless requested
225+
if (
226+
not include_remote_state
227+
and resource.get("type") == "terraform_remote_state"
228+
):
229+
continue
213230
yield from find_tagged_secret(resource["address"], resource["values"])
214231
return
215232

@@ -309,14 +326,20 @@ def get_users(terraform_state: Dict) -> Dict[str, Tuple[str, str]]:
309326
return user_creds
310327

311328

312-
def get_resource_secrets(terraform_state: Dict) -> Dict[str, str]:
329+
def get_resource_secrets(
330+
terraform_state: Dict, include_remote_state: bool
331+
) -> Dict[str, str]:
313332
"""Collect secrets from tagged Terraform resources."""
314333
secrets: Dict[str, str] = dict()
315334
logging.info("Searching Terraform state for tagged resources.")
316-
for secret_name, secret_value in parse_tagged_resources(terraform_state):
335+
for secret_name, secret_value in parse_tagged_resources(
336+
terraform_state, include_remote_state
337+
):
317338
logging.info(f"Found secret: {secret_name}")
318339
secrets[secret_name] = secret_value
319-
for secret_name, secret_value in parse_tagged_outputs(terraform_state):
340+
for secret_name, secret_value in parse_tagged_outputs(
341+
terraform_state, include_remote_state
342+
):
320343
logging.info(f"Found secret: {secret_name}")
321344
secrets[secret_name] = secret_value
322345
return secrets
@@ -425,6 +448,7 @@ def main() -> int:
425448
github_env: str = validated_args["--env"]
426449
github_token_to_save: str = validated_args["<github-personal-access-token>"]
427450
log_level: str = validated_args["--log-level"]
451+
include_remote_state: bool = validated_args["--remote-state"]
428452
repo_name: str = validated_args["--repo"]
429453
state_filename: str = validated_args["--state"]
430454
github_token: str = validated_args["--token"]
@@ -467,7 +491,9 @@ def main() -> int:
467491
user_secrets: Dict[str, str] = create_user_secrets(user_creds)
468492

469493
# Secrets created from tagged resources. Names mapped to value.
470-
resource_secrets: Dict[str, str] = get_resource_secrets(terraform_state)
494+
resource_secrets: Dict[str, str] = get_resource_secrets(
495+
terraform_state, include_remote_state
496+
)
471497

472498
# Check if there are overlaps in the keys.
473499
if not user_secrets.keys().isdisjoint(resource_secrets.keys()):

0 commit comments

Comments
 (0)