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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ ADDITIONAL_TF_OVERRIDE_LOCATIONS=/path/to/module1,path/to/module2 tflocal plan

## Change Log

* v0.26.0: Fix compatibility with `python-hcl2` v8+ by using `SerializationOptions` to handle quoted dict keys, block metadata, and comments
* v0.25.0: Improve `s3control` local endpoint override and respect `AWS_ENDPOINT_URL` configuration for `mwaa`
* v0.24.1: Exclude broken `python-hcl2` version from requirements
* v0.24.0: Add support to return `terraform-local` version when calling `tflocal -version` and fix AWS provider detection
Expand Down
9 changes: 7 additions & 2 deletions bin/tflocal
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ if os.path.isdir(os.path.join(PARENT_FOLDER, ".venv")):

from localstack_client import config # noqa: E402
import hcl2 # noqa: E402
from hcl2 import SerializationOptions # noqa: E402

HCL2_SERIALIZATION_OPTIONS = SerializationOptions(
Comment on lines +29 to +31
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

this is mostly a note for later and not something actionable for this PR: I don't know if we explicitly set some versions on hcl2 for some reasons, and if we're aiming of compatibility. There could be a world when we want to keep compatibility with older versions, and would have to try to import the SerializationOptions and fallback if it failed, and pass some kwargs to load.

But I think hcl2>=8 is just the right version to use, so we can see later, I think we'll need to rework how we package this!

strip_string_quotes=True, explicit_blocks=False, with_comments=False
)

DRY_RUN = str(os.environ.get("DRY_RUN")).strip().lower() in ["1", "true"]
DEFAULT_REGION = "us-east-1"
Expand Down Expand Up @@ -611,7 +616,7 @@ def parse_tf_files() -> dict:
for _file in glob.glob("*.tf"):
try:
with open(_file, "r") as fp:
result[_file] = hcl2.load(fp)
result[_file] = hcl2.load(fp, serialization_options=HCL2_SERIALIZATION_OPTIONS)
except Exception as e:
print(f'Unable to parse "{_file}" as HCL file: {e}')
return result
Expand All @@ -634,7 +639,7 @@ def get_provider_version_from_lock_file() -> Optional[version.Version]:

provider_version = None
with open(lock_file, "r") as fp:
result = hcl2.load(fp)
result = hcl2.load(fp, serialization_options=HCL2_SERIALIZATION_OPTIONS)
for provider in result.get("provider", []):
for provider_name, provider_config in provider.items():
if provider_name.endswith(AWS_PROVIDER_NAME_SUFFIX):
Expand Down
4 changes: 2 additions & 2 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[metadata]
name = terraform-local
version = 0.25.0
version = 0.26.0
url = https://github.com/localstack/terraform-local
author = LocalStack Team
author_email = info@localstack.cloud
Expand Down Expand Up @@ -28,7 +28,7 @@ packages = find:

install_requires =
localstack-client
python-hcl2!=7.3.0
python-hcl2>=8
packaging

[options.extras_require]
Expand Down
19 changes: 12 additions & 7 deletions tests/test_apply.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@
import boto3
import pytest
import hcl2
from hcl2 import SerializationOptions

HCL2_SERIALIZATION_OPTIONS = SerializationOptions(
strip_string_quotes=True, explicit_blocks=False, with_comments=False
)

# TODO set up the tests to run with tox so we can run the tests with different python versions

Expand Down Expand Up @@ -385,7 +390,7 @@ def test_s3_remote_data_source_with_workspace(monkeypatch):
assert check_override_file_exists(override_file)

with open(override_file, "r") as fp:
result = hcl2.load(fp)
result = hcl2.load(fp, serialization_options=HCL2_SERIALIZATION_OPTIONS)
assert result["data"][0]["terraform_remote_state"]["terraform_infra"]["workspace"] == "${terraform.workspace}"
assert result["data"][1]["terraform_remote_state"]["build_infra"]["workspace"] == "build"

Expand Down Expand Up @@ -432,7 +437,7 @@ def test_versioned_endpoints(monkeypatch, provider_version):
assert check_override_file_exists(override_file)

with open(override_file, "r") as fp:
result = hcl2.load(fp)
result = hcl2.load(fp, serialization_options=HCL2_SERIALIZATION_OPTIONS)
endpoints = result["provider"][0]["aws"]["endpoints"][0]
if provider_version == "5.99.1":
assert "iotanalytics" in endpoints
Expand Down Expand Up @@ -486,7 +491,7 @@ def test_subdomain_endpoints(monkeypatch, endpoint_host):
assert check_override_file_exists(override_file)

with open(override_file, "r") as fp:
result = hcl2.load(fp)
result = hcl2.load(fp, serialization_options=HCL2_SERIALIZATION_OPTIONS)
endpoints = result["provider"][0]["aws"]["endpoints"][0]
assert "s3control" in endpoints
assert "mwaa" in endpoints
Expand Down Expand Up @@ -570,7 +575,7 @@ def test_service_endpoint_alias_replacements(monkeypatch):
def check_override_file_content(override_file):
try:
with open(override_file, "r") as fp:
result = hcl2.load(fp)
result = hcl2.load(fp, serialization_options=HCL2_SERIALIZATION_OPTIONS)
result = result["provider"][0]["aws"]
except Exception as e:
raise Exception(f'Unable to parse "{override_file}" as HCL file: {e}')
Expand Down Expand Up @@ -616,7 +621,7 @@ def test_s3_backend_configs_merge(monkeypatch):
def check_override_file_backend_extra_content(override_file):
try:
with open(override_file, "r") as fp:
result = hcl2.load(fp)
result = hcl2.load(fp, serialization_options=HCL2_SERIALIZATION_OPTIONS)
result = result["terraform"][0]["backend"][0]["s3"]
except Exception as e:
raise Exception(f'Unable to parse "{override_file}" as HCL file: {e}')
Expand Down Expand Up @@ -690,7 +695,7 @@ def check_override_file_backend_endpoints_content(override_file, is_legacy: bool
}
try:
with open(override_file, "r") as fp:
result = hcl2.load(fp)
result = hcl2.load(fp, serialization_options=HCL2_SERIALIZATION_OPTIONS)
result = result["terraform"][0]["backend"][0]["s3"]
except Exception as e:
print(f'Unable to parse "{override_file}" as HCL file: {e}')
Expand Down Expand Up @@ -727,7 +732,7 @@ def test_provider_aliases_ignored(monkeypatch):
def check_override_file_content_for_alias(override_file):
try:
with open(override_file, "r") as fp:
result = hcl2.load(fp)
result = hcl2.load(fp, serialization_options=HCL2_SERIALIZATION_OPTIONS)
result = result["provider"]
except Exception as e:
raise Exception(f'Unable to parse "{override_file}" as HCL file: {e}')
Expand Down
Loading