Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[terraform/utils] Debug terraform-lint CI #6

Open
wants to merge 21 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
6e2c436
updated variables.py to diff generated content and content found in t…
ethangraham2001 Sep 6, 2024
7078daa
ran formatter
ethangraham2001 Sep 6, 2024
5efd549
removed redundant print
ethangraham2001 Sep 6, 2024
425fb2d
Updated comments, added logs.
ethangraham2001 Sep 6, 2024
40d0393
added new linting step to Makefile
ethangraham2001 Sep 9, 2024
8c0d645
bash script now takes argument which is passed to variables.py
ethangraham2001 Sep 9, 2024
5707cd5
updated how makefile calls terraform lint
ethangraham2001 Sep 9, 2024
74ff5c2
updated flag name and comments
ethangraham2001 Sep 9, 2024
4430cc0
updated flag name to lint
ethangraham2001 Sep 9, 2024
d840b15
updated makefile and bash script to remove cd into utils dir
ethangraham2001 Sep 9, 2024
f00892b
remove SCRIPT_DIR references from generate_terraform_variables.sh
ethangraham2001 Sep 9, 2024
a6f83b7
removed difflib dep, added script dir back as .
ethangraham2001 Sep 9, 2024
d5ee070
removed usage of script dir, using base_dir
ethangraham2001 Sep 10, 2024
6028bab
fix typo
ethangraham2001 Sep 10, 2024
0bcd8af
shell lintn
ethangraham2001 Sep 10, 2024
73d67d0
added --user flag to utils/Dockerfile
ethangraham2001 Sep 10, 2024
fecf59e
updated dockerfile to use pip3 instead of pip
ethangraham2001 Sep 10, 2024
c302a83
added venv to dockerfile
ethangraham2001 Sep 10, 2024
1614007
backup
ethangraham2001 Sep 10, 2024
d847d5a
updated generate_terraform_variables.sh
ethangraham2001 Sep 10, 2024
829f91d
shell lint
ethangraham2001 Sep 10, 2024
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
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ go-lint:
.PHONY: terraform-lint
terraform-lint:
docker run --rm -w /opt/dss -v ./deploy:/opt/dss/deploy -e TF_LOG=TRACE hashicorp/terraform fmt -recursive -check
./deploy/infrastructure/utils/generate_terraform_variables.sh --lint

# This mirrors the hygiene-tests continuous integration workflow job (.github/workflows/ci.yml)
.PHONY: hygiene-tests
Expand Down
3 changes: 3 additions & 0 deletions deploy/infrastructure/utils/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
FROM python:3.10


RUN pip install python-hcl2

RUN ls

WORKDIR /app
20 changes: 15 additions & 5 deletions deploy/infrastructure/utils/generate_terraform_variables.sh
Original file line number Diff line number Diff line change
@@ -1,13 +1,23 @@
#!/usr/bin/env bash
set -e

SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
set -eo pipefail

OS=$(uname)
if [[ "$OS" == "Darwin" ]]; then
# OSX uses BSD readlink
BASEDIR="$(dirname "$0")"
else
BASEDIR=$(readlink -e "$(dirname "$0")")
fi
cd "${BASEDIR}"

docker build -t terraform-variables:latest .
docker run \
-v "${SCRIPT_DIR}/":/app/utils:rw \
-v "${SCRIPT_DIR}/../dependencies":/app/examples:rw \
-v "${SCRIPT_DIR}/../modules":/app/modules:rw \
-v "${BASEDIR}/":/app/utils:rw \
-v "${BASEDIR}/../dependencies":/app/dependencies:rw \
-v "${BASEDIR}/../modules":/app/modules:rw \
-v "${BASEDIR}/../../operations":/operations:rw \
-w /app/utils \
terraform-variables \
ls ../ && python variables.py
/bin/bash -c "python variables.py $*"
96 changes: 81 additions & 15 deletions deploy/infrastructure/utils/variables.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
from os.path import isfile, join, abspath, dirname, exists
from typing import Dict, List, Tuple
import hcl2
import argparse
import sys

DEFINITIONS_PATH = join(abspath(dirname(__file__)), "definitions")
GENERATED_TFVARS_MD_FILENAME = "TFVARS.gen.md"
Expand All @@ -20,10 +22,7 @@

# Variables per project
# For all */terraform-*
GLOBAL_VARIABLES = [
"app_hostname",
"crdb_hostname_suffix"
]
GLOBAL_VARIABLES = ["app_hostname", "crdb_hostname_suffix"]

# dependencies/terraform-commons-dss
COMMONS_DSS_VARIABLES = GLOBAL_VARIABLES + [
Expand All @@ -38,14 +37,14 @@
"crdb_cluster_name",
"crdb_locality",
"crdb_external_nodes",
"kubernetes_namespace"
"kubernetes_namespace",
]

# dependencies/terraform-*-kubernetes
COMMON_KUBERNETES_VARIABLES = GLOBAL_VARIABLES + [
"cluster_name",
"node_count",
"kubernetes_version"
"kubernetes_version",
]

# dependencies/terraform-google-kubernetes
Expand All @@ -70,7 +69,7 @@
"aws_region",
"aws_instance_type",
"aws_route53_zone_id",
"aws_iam_permissions_boundary"
"aws_iam_permissions_boundary",
] + COMMON_KUBERNETES_VARIABLES

# modules/terraform-aws-dss
Expand All @@ -88,9 +87,7 @@
"../dependencies/terraform-aws-kubernetes": AWS_KUBERNETES_VARIABLES,
"../dependencies/terraform-google-kubernetes": GOOGLE_KUBERNETES_VARIABLES,
"../dependencies/terraform-commons-dss": COMMONS_DSS_VARIABLES,
"../../operations/ci/aws-1": list(
dict.fromkeys(AWS_MODULE_VARIABLES)
)
"../../operations/ci/aws-1": list(dict.fromkeys(AWS_MODULE_VARIABLES)),
}


Expand Down Expand Up @@ -175,9 +172,11 @@ def comment(content: str) -> str:
return commented_lines


def get_variables_tf_content(variables: List[str], definitions: Dict[str, str]) -> str:
def get_variables_gen_tf_content(
variables: List[str], definitions: Dict[str, str]
) -> str:
"""
Generate the content of variables.tf (Terraform definitions) based
Generate the content of variables.gen.tf (Terraform definitions) based
on the `variables` list. `variables` contains the variables names to
include in the content. `definitions` contains the definitions of all
available variables.
Expand Down Expand Up @@ -234,9 +233,9 @@ def write_files(definitions: Dict[str, str]):
for path, variables in PROJECT_VARIABLES.items():
project_name = path.split("/")[-1]

# Generate variables.tf definition
# Generate variables.gen.tf definition
var_filename = join(path, GENERATED_VARIABLES_FILENAME)
content = get_variables_tf_content(variables, definitions)
content = get_variables_gen_tf_content(variables, definitions)
write_file(var_filename, content)

if is_example_project(path):
Expand All @@ -249,6 +248,73 @@ def write_files(definitions: Dict[str, str]):
write_file(tfvars_md_filename, content)


def read_file(file_path: str) -> str:
"""
Reads a file and returns its content

Arguments:
file_path: the relative path of the file to be read from
Returns:
the content of the file as a str
"""
with open(file_path, "r") as file:
content = file.read()
return content


def diff_files(definitions: Dict[str, str]) -> bool:
"""
Generates the `variables.gen.tf` file content in memory and diffs it
against the `variables.get.tf` files found on disk

Arguments:
definitions: a dict where the keys are the terraform variable names,
and the valuies are the content of that file.
Returns:
true iff the generated content and locally stored content are equal
string values
"""
for path, variables in PROJECT_VARIABLES.items():
# Generate variables.gen.tf definition
var_filename = join(path, GENERATED_VARIABLES_FILENAME)
generated_content = get_variables_gen_tf_content(variables, definitions)

try:
actual_content = read_file(var_filename)
except Exception as e:
print(f"Error reading {var_filename}: {e}")
return False

if generated_content != actual_content:
return False

return True


if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument(
"--lint",
action="store_true",
help="Evaluates the differences between the generated `variables.gen.tf` files and the ones\
stored locally without modifiying existing files or writing any\
results out to disk.\
Exits with code 0 on success and if there are no differences, else exits with code 1",
)
args = parser.parse_args()

definitions = load_tf_definitions()
write_files(definitions)

if args.lint:
if not diff_files(definitions):
print(
"variables.py: generated content was NOT equal to local variables.gen.tf content"
)
sys.exit(1)
else:
print(
"variables.py: generated content was equal to local variables.gen.tf content"
)
sys.exit(0)
else:
write_files(definitions)
Loading