Skip to content
Merged
Show file tree
Hide file tree
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
3 changes: 2 additions & 1 deletion .github/release-drafter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ version-resolver:
- 'patch'
default: patch
footer: |
*REMINDER:* please remember to add or update the Version Compatibility section before publishing a release draft.
---
⚠️ *REMINDER:* please remember to add or update the Version Compatibility section before publishing a release draft.
template: |
## Changes

Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/release-pypi-build-push-package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ jobs:
build_push:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
with:
ref: master

- uses: actions/setup-python@v2
- uses: actions/setup-python@v5
with:
python-version: '3.9'
python-version: '3.13'

- name: Install Poetry
run: |
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/release-pypi-build-push-test-package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ jobs:
build_push:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4

- uses: actions/setup-python@v2
- uses: actions/setup-python@v5
with:
python-version: '3.9'
python-version: '3.13'

- name: Install Poetry
run: |
Expand Down
16 changes: 8 additions & 8 deletions .github/workflows/tests-integration.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ jobs:
strategy:
max-parallel: 1
matrix:
python-version: ['3.9.15', '3.10.8', '3.11.8', '3.12.7']
toolbox-image-tag: ['1.3.5-0.2.0', '1.5.0-0.2.0', '1.6.0-0.2.0']
python-version: ['3.9', '3.10', '3.11', '3.12', '3.13']
toolbox-image-tag: ['1.3.5-0.2.3', '1.5.0-0.2.3', '1.6.0-0.2.3']
steps:
- name: Checkout base branch
uses: actions/checkout@v3
Expand Down Expand Up @@ -141,7 +141,7 @@ jobs:
printf "[INFO] Testing terraform\n"

printf "[INFO] Initializing layer\n"
leverage tf init --skip-validation
leverage terraform init --skip-validation

working-directory: ../theadamproject/security/us-east-1/base-tf-backend

Expand Down Expand Up @@ -203,19 +203,19 @@ jobs:
run: |

printf "[INFO] Initializing layer\n"
leverage tf init --layers cli-test-layer,base-identities
leverage terraform init --layers cli-test-layer,base-identities

printf "[INFO] Generating plan\n"
leverage tf plan --layers cli-test-layer
leverage terraform plan --layers cli-test-layer

printf "[INFO] Applying changes\n"
leverage tf apply -auto-approve --layers cli-test-layer
leverage terraform apply -auto-approve --layers cli-test-layer

printf "[INFO] Checking if all changes were applied\n"
leverage tf plan -detailed-exitcode --layers cli-test-layer
leverage terraform plan -detailed-exitcode --layers cli-test-layer
[[ $? -eq 2 ]] && printf "[WARN] There are still remaining changes\n"
[[ $? -eq 0 ]] && printf "[INFO] Apply checks out\n"
Comment on lines 205 to 217
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Bug: exit code checks are incorrect due to clobbered $?.

After plan -detailed-exitcode, $? is read once, then the next [[ ... ]] overwrites it, so the second check no longer inspects the plan’s exit code. Capture it once and branch.

-          leverage terraform plan -detailed-exitcode --layers cli-test-layer
-          [[ $? -eq 2 ]] && printf "[WARN] There are still remaining changes\n"
-          [[ $? -eq 0 ]] && printf "[INFO] Apply checks out\n"
+          leverage terraform plan -detailed-exitcode --layers cli-test-layer
+          plan_rc=$?
+          if [[ $plan_rc -eq 2 ]]; then
+            printf "[WARN] There are still remaining changes\n"
+          elif [[ $plan_rc -eq 0 ]]; then
+            printf "[INFO] Apply checks out\n"
+          else
+            printf "[ERROR] Unexpected terraform plan exit code: %d\n" "$plan_rc"
+            exit $plan_rc
+          fi
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
printf "[INFO] Initializing layer\n"
leverage tf init --layers cli-test-layer,base-identities
leverage terraform init --layers cli-test-layer,base-identities
printf "[INFO] Generating plan\n"
leverage tf plan --layers cli-test-layer
leverage terraform plan --layers cli-test-layer
printf "[INFO] Applying changes\n"
leverage tf apply -auto-approve --layers cli-test-layer
leverage terraform apply -auto-approve --layers cli-test-layer
printf "[INFO] Checking if all changes were applied\n"
leverage tf plan -detailed-exitcode --layers cli-test-layer
leverage terraform plan -detailed-exitcode --layers cli-test-layer
[[ $? -eq 2 ]] && printf "[WARN] There are still remaining changes\n"
[[ $? -eq 0 ]] && printf "[INFO] Apply checks out\n"
printf "[INFO] Checking if all changes were applied\n"
leverage terraform plan -detailed-exitcode --layers cli-test-layer
plan_rc=$?
if [[ $plan_rc -eq 2 ]]; then
printf "[WARN] There are still remaining changes\n"
elif [[ $plan_rc -eq 0 ]]; then
printf "[INFO] Apply checks out\n"
else
printf "[ERROR] Unexpected terraform plan exit code: %d\n" "$plan_rc"
exit $plan_rc
fi
🤖 Prompt for AI Agents
.github/workflows/tests-integration.yaml around lines 205 to 217: the script
runs `leverage terraform plan -detailed-exitcode` then checks `$?` twice, but
the first `[[ ... ]]` test overwrites `$?` so the second check inspects the test
command's exit status instead of the plan's; capture the plan exit code
immediately into a variable (e.g., plan_exit=$?) and then use that variable for
the conditional branches so both checks examine the original plan result,
leaving the rest of the messages intact.


printf "[INFO] Destroying all generated created resources\n"
leverage tf destroy -auto-approve --layers cli-test-layer
leverage terraform destroy -auto-approve --layers cli-test-layer
working-directory: ../theblairwitchproject/apps-devstg/global
4 changes: 2 additions & 2 deletions .github/workflows/tests-unit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.9', '3.10', '3.11', '3.12']
python-version: ['3.9', '3.10', '3.11', '3.12', '3.13']
steps:
- uses: actions/checkout@v3

Expand Down Expand Up @@ -38,7 +38,7 @@ jobs:
shell: bash

- name: Report Coveralls
if: matrix.python-version == '3.9' # Run this for the first python version only!
if: matrix.python-version == '3.13' # Run this for the last python version only!
uses: coverallsapp/github-action@v2
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
14 changes: 8 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,13 @@ PROJECT=bb
MFA_ENABLED=false

# Terraform
TERRAFORM_IMAGE_TAG=1.5.0-0.2.0
TF_IMAGE_TAG=1.5.0-0.2.0
```

So, if you have created a project with version <1.8.0 and want to use it with version >=1.8.0 you should:

- remove TERRAFORM_IMAGE_NAME line
- update TERRAFORM_IMAGE_TAG from this form '9.9.9' to this one '9.9.9-9.9.9'.
- update TF_IMAGE_TAG from this form '9.9.9' to this one '9.9.9-9.9.9'.

For the second item you can check the version [here](https://hub.docker.com/r/binbash/leverage-toolbox/tags).

Expand All @@ -70,6 +70,7 @@ Leverage CLI explicitly supports the following Python versions:
- Python 3.10.x
- Python 3.11.x
- Python 3.12.x
- Python 3.13.x

These versions are not only supported but are also the only versions used in our CI/CD pipelines to ensure compatibility
and performance. This rigorous testing helps prevent compatibility issues and ensures that the Leverage CLI performs as
Expand Down Expand Up @@ -111,14 +112,15 @@ pyenv install 3.9.7
pyenv install 3.10.1
pyenv install 3.11.8
pyenv install 3.12.7
pyenv install 3.13.6
```

4. Create a virtual environment for the leverage project:

Create a virtual environment for your project using Python 3.9.7:
Create a virtual environment for your project using Python 3.13.x:

```bash
pyenv virtualenv 3.9.7 leverage_py_39_venv
pyenv virtualenv 3.13.6 leverage_py_313_venv
```

5. Set your virtual environment to be used in the project:
Expand All @@ -127,10 +129,10 @@ To set this virtual environment as the local environment for your project, navig

```bash
cd <path_to_leverage_project_root>
pyenv local leverage_py_39_venv
pyenv local leverage_py_313_venv
```

This setup commands `pyenv` to use `leverage_py_39_venv` as the local Python version for your project directory,
This setup commands `pyenv` to use `leverage_py_313_venv` as the local Python version for your project directory,
ensuring that all Python operations within this directory use this isolated environment.

## Setting up development environment
Expand Down
10 changes: 5 additions & 5 deletions leverage/container.py
Original file line number Diff line number Diff line change
Expand Up @@ -490,10 +490,10 @@ def __init__(self, client, terraform=False, mounts=None, env_vars=None):
if self.paths.tf_cache_dir:
# then mount it too into the container
self.environment["TF_PLUGIN_CACHE_DIR"] = self.paths.tf_cache_dir
# given that terraform use symlinks to point from the .terraform folder into the plugin folder
# we need to use the same directory inside the container
# given that opentofu/terraform uses symlinks to point from the .terraform folder
# into the plugin folder we need to use the same directory inside the container
# otherwise symlinks will be broken once outside the container
# which will break terraform usage outside Leverage
# which will break opentofu/terraform usage outside Leverage
self.mounts.append(Mount(source=self.paths.tf_cache_dir, target=self.paths.tf_cache_dir, type="bind"))
if SSH_AUTH_SOCK is not None:
self.mounts.append(Mount(source=SSH_AUTH_SOCK, target="/ssh-agent", type="bind"))
Expand Down Expand Up @@ -528,7 +528,7 @@ def auth_method(self) -> str:

@property
def tf_default_args(self):
"""Array of strings containing all valid config files for layer as parameters for Terraform"""
"""Array of strings containing all valid config files for layer as parameters for OpenTofu/Terraform"""
common_config_files = [
f"-var-file={self.paths.guest_config_file(common_file)}"
for common_file in self.paths.common_config_dir.glob("*.tfvars")
Expand Down Expand Up @@ -669,7 +669,7 @@ def set_backend_key(self, skip_validation=False):
raise KeyError()
except (KeyError, IndexError):
logger.error(
"[red]✘[/red] Malformed [bold]config.tf[/bold] file. Missing Terraform backend block. In some cases you may want to skip this check by using the --skip-validation flag, e.g. the first time you initialize a terraform-backend layer."
"[red]✘[/red] Malformed [bold]config.tf[/bold] file. Missing backend block. In some cases you may want to skip this check by using the --skip-validation flag, e.g. the first time you initialize a tf-backend layer."
)
raise Exit(1)
except Exception as e:
Expand Down
4 changes: 2 additions & 2 deletions leverage/modules/credentials.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ def _ask_for_credentials_location():
{
"type": "select",
"name": "input_type",
"message": "Select the means by which you'll provide the programatic keys:",
"message": "Select the means by which you'll provide the programmatic keys:",
"qmark": ">",
"choices": [
{"name": "Path to an access keys file obtained from AWS", "value": "path"},
Expand Down Expand Up @@ -312,7 +312,7 @@ def _load_configs_for_credentials():
env_config = AWSCLI.env_conf

terraform_config = {}
logger.info("Loading Terraform common configuration.")
logger.info("Loading tf common configuration.")
terraform_config = AWSCLI.paths.common_conf

config_values = {}
Expand Down
5 changes: 3 additions & 2 deletions leverage/modules/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,8 +203,9 @@ def _render_templates(template_files, config, source=TEMPLATE_DIR, destination=P
template_location = template_file.relative_to(TEMPLATES_REPO_DIR)

template = JINJA_ENV.get_template(template_location.as_posix())
if not "terraform_image_tag" in config:
if "terraform_image_tag" not in config:
config["terraform_image_tag"] = __toolbox_version__

rendered_template = template.render(config)

rendered_location = template_file.relative_to(source)
Expand Down Expand Up @@ -324,7 +325,7 @@ def create():
_render_project_template(config=config)

# Format the code correctly
logger.info("Reformatting terraform configuration to the standard style.")
logger.info("Reformatting configuration to the standard style.")

terraform = TFContainer(get_docker_client())
terraform.ensure_image()
Expand Down
5 changes: 2 additions & 3 deletions leverage/path.py
Original file line number Diff line number Diff line change
Expand Up @@ -275,13 +275,12 @@ def check_for_layer_location(self, path: Path = None):
"""Make sure the command is being run at layer level. If not, bail."""
path = path or self.cwd
if path in (self.common_config_dir, self.account_config_dir):
raise ExitError(1, "Currently in a configuration directory, no Terraform command can be run here.")
raise ExitError(1, "Currently in a configuration directory, no OpenTofu/Terraform command can be run here.")

if path in (self.root_dir, self.account_dir):
raise ExitError(
1,
"Terraform commands cannot run neither in the root of the project or in"
" the root directory of an account.",
"This command cannot run neither in the root of the project or in" " the root directory of an account.",
)

if not list(path.glob("*.tf")):
Expand Down
Loading
Loading