Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 65 additions & 31 deletions project_setup/scripts/terraform-to-secrets
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,64 @@ def get_terraform_state(filename: str = None) -> Dict:
return json_state


def find_tagged_secret(
resource_name: str, resource_data: Dict
) -> Generator[Tuple[str, str], None, None]:
"""Extract a tagged secret from a resource."""
# Ensure "tags" key exists in resource_data and if it does, make sure
# its value is not None. Both of these cases can occur.
tags: Dict[str, str]
if "tags" not in resource_data or resource_data.get("tags") is None:
tags = dict()
else:
tags = resource_data["tags"]

secret_name: Optional[str] = tags.get(GITHUB_SECRET_NAME_TAG)
lookup_tag: Optional[str] = tags.get(GITHUB_SECRET_TERRAFORM_LOOKUP_TAG)
secret_value: Optional[str]
if secret_name:
logging.debug(
f"Found {GITHUB_SECRET_NAME_TAG} on {resource_name} "
f"with value {secret_name}"
)
if lookup_tag:
logging.debug(
f"Found {GITHUB_SECRET_TERRAFORM_LOOKUP_TAG} on "
f"{resource_name} with value {lookup_tag}"
)
secret_value = resource_data.get(lookup_tag)
if secret_value is None:
logging.warning(f"Could not lookup value with key {lookup_tag}")
else:
logging.debug(f"Looked up value: {secret_value}")
yield secret_name, secret_value
else:
logging.warning(
f"Missing {GITHUB_SECRET_TERRAFORM_LOOKUP_TAG} on " f"{resource_name}."
)
return


def find_outputs(terraform_state: Dict) -> Generator[Dict, None, None]:
"""Search for resources with outputs in the Terraform state."""
for resource in terraform_state["values"]["root_module"]["resources"]:
if resource.get("values", dict()).get("outputs", dict()):
yield resource["values"]["outputs"]


def parse_tagged_outputs(
terraform_state: Dict,
) -> Generator[Tuple[str, str], None, None]:
"""Search all outputs for tags requesting the creation of a secret."""
for outputs in find_outputs(terraform_state):
for output_name, output_data in outputs.items():
for secret_name, secret_value in find_tagged_secret(
output_name, output_data
):
yield secret_name, secret_value
return


def find_resources(
terraform_state: Dict, resource_type: Optional[str]
) -> Generator[Dict, None, None]:
Expand Down Expand Up @@ -129,37 +187,10 @@ def parse_tagged_resources(
) -> Generator[Tuple[str, str], None, None]:
"""Search all resources for tags requesting the creation of a secret."""
for resource in find_resources(terraform_state, None):
# Ensure "tags" key exists in resource["values"] and if it does,
# make sure its value is not None. Both of these cases can occur.
tags: Dict[str, str]
if "tags" not in resource["values"] or resource["values"].get("tags") is None:
tags = dict()
else:
tags = resource["values"]["tags"]
secret_name: Optional[str] = tags.get(GITHUB_SECRET_NAME_TAG)
lookup_tag: Optional[str] = tags.get(GITHUB_SECRET_TERRAFORM_LOOKUP_TAG)
secret_value: str
if secret_name:
logging.debug(
f"Found {GITHUB_SECRET_NAME_TAG} on {resource['address']} "
f"with value {secret_name}"
)
if lookup_tag:
logging.debug(
f"Found {GITHUB_SECRET_TERRAFORM_LOOKUP_TAG} on "
f"{resource['address']} with value {lookup_tag}"
)
secret_value = resource["values"].get(lookup_tag)
if secret_value is None:
logging.warning(f"Could not lookup value with key {lookup_tag}")
else:
logging.debug(f"Looked up value: {secret_value}")
yield secret_name, secret_value
else:
logging.warning(
f"Missing {GITHUB_SECRET_TERRAFORM_LOOKUP_TAG} on "
f"{resource['address']}."
)
for secret_name, secret_value in find_tagged_secret(
resource["address"], resource["values"]
):
yield secret_name, secret_value
return


Expand Down Expand Up @@ -249,6 +280,9 @@ def get_resource_secrets(terraform_state: Dict) -> Dict[str, str]:
for secret_name, secret_value in parse_tagged_resources(terraform_state):
logging.info(f"Found secret: {secret_name}")
secrets[secret_name] = secret_value
for secret_name, secret_value in parse_tagged_outputs(terraform_state):
logging.info(f"Found secret: {secret_name}")
secrets[secret_name] = secret_value
return secrets


Expand Down