Skip to content

TerraformStack

laktory.models.TerraformStack ¤

Bases: BaseModel

A Terraform stack is terraform-specific flavor of the laktory.models.Stack. It re-structure the attributes to be aligned with a terraform json file.

It is generally not instantiated directly, but rather created using laktory.models.Stack.to_terraform().

Functions¤

model_dump ¤

model_dump(*args, **kwargs)

Serialize model to match the structure of a Terraform json file.

Source code in laktory/models/stacks/terraformstack.py
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
def model_dump(self, *args, **kwargs) -> dict[str, Any]:
    """Serialize model to match the structure of a Terraform json file."""
    settings.singular_serialization = True
    kwargs["exclude_none"] = kwargs.get("exclude_none", True)
    d = super().model_dump(*args, **kwargs)

    # Special treatment of resources
    d["resource"] = defaultdict(lambda: {})
    d["data"] = defaultdict(lambda: {})
    for r in self.resources.values():
        if r.lookup_existing:
            d["data"][r.terraform_resource_lookup_type][
                r.resource_name
            ] = r.lookup_existing.model_dump()
        else:
            _d = r.terraform_properties
            d["resource"][r.terraform_resource_type][r.resource_name] = _d
    d["data"] = dict(d["data"])
    if len(d["data"]) == 0:
        del d["data"]
    d["resource"] = dict(d["resource"])
    settings.singular_serialization = False

    # Terraform JSON requires the keyword "resources." to be removed and the
    # resource_name to be replaced with resource_type.resource_name.
    patterns = []
    for r in list(self.resources.values()) + list(self.providers.values()):
        k0 = r.resource_name
        k1 = f"{r.terraform_resource_type}.{r.resource_name}"
        # special treatment for data sources
        if r.lookup_existing:
            k1 = f"data.{r.terraform_resource_lookup_type}.{r.resource_name}"

        if isinstance(r, BaseProvider):
            # ${resources.resource_name} -> resource_name
            pattern = r"\$\{resources." + k0 + "}"
            self.variables[pattern] = k0
            patterns += [pattern]

        else:
            # ${resources.resource_name} -> resource_type.resource_name
            pattern = r"\$\{resources\." + k0 + r"\}"
            self.variables[pattern] = k1
            patterns += [pattern]

            # ${resources.resource_name.property} -> ${resource_type.resource_name.property}
            pattern = r"\$\{resources\." + k0 + r"\.(.*?)\}"
            self.variables[pattern] = rf"${{{k1}.\1}}"
            patterns += [pattern]

    d = self.inject_vars(d)
    for p in patterns:
        del self.variables[p]

    return d

write ¤

write()

Write Terraform json configuration file

RETURNS DESCRIPTION
str

Filepath of the configuration file

Source code in laktory/models/stacks/terraformstack.py
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
def write(self) -> str:
    """
    Write Terraform json configuration file

    Returns
    -------
    :
        Filepath of the configuration file
    """
    filepath = os.path.join(CACHE_ROOT, "stack.tf.json")

    if not os.path.exists(CACHE_ROOT):
        os.makedirs(CACHE_ROOT)

    text = json.dumps(self.model_dump(), indent=4)

    # Special treatment of providers with aliases
    for _, p in self.providers.items():
        if p.alias is not None:
            text = text.replace(
                f'"{p.resource_name}":',
                f'"{p.resource_name_without_alias}":',
            )

    # Output
    with open(filepath, "w") as fp:
        fp.write(text)

    return filepath

init ¤

init(flags=None)

Runs terraform init

PARAMETER DESCRIPTION
flags

List of flags / options for pulumi plan

TYPE: list[str] DEFAULT: None

Source code in laktory/models/stacks/terraformstack.py
178
179
180
181
182
183
184
185
186
187
def init(self, flags: list[str] = None) -> None:
    """
    Runs `terraform init`

    Parameters
    ----------
    flags:
        List of flags / options for pulumi plan
    """
    self._call("init", flags=flags)

plan ¤

plan(flags=None)

Runs terraform plan

PARAMETER DESCRIPTION
flags

List of flags / options for pulumi plan

TYPE: list[str] DEFAULT: None

Source code in laktory/models/stacks/terraformstack.py
189
190
191
192
193
194
195
196
197
198
def plan(self, flags: list[str] = None) -> None:
    """
    Runs `terraform plan`

    Parameters
    ----------
    flags:
        List of flags / options for pulumi plan
    """
    self._call("plan", flags=flags)

apply ¤

apply(flags=None)

Runs terraform apply

PARAMETER DESCRIPTION
flags

List of flags / options for terraform apply

TYPE: list[str] DEFAULT: None

Source code in laktory/models/stacks/terraformstack.py
200
201
202
203
204
205
206
207
208
209
def apply(self, flags: list[str] = None):
    """
    Runs `terraform apply`

    Parameters
    ----------
    flags:
        List of flags / options for terraform apply
    """
    self._call("apply", flags=flags)

destroy ¤

destroy(flags=None)

Runs terraform destroy

PARAMETER DESCRIPTION
flags

List of flags / options for terraform destroy

TYPE: list[str] DEFAULT: None

Source code in laktory/models/stacks/terraformstack.py
211
212
213
214
215
216
217
218
219
220
def destroy(self, flags: list[str] = None):
    """
    Runs `terraform destroy`

    Parameters
    ----------
    flags:
        List of flags / options for terraform destroy
    """
    self._call("destroy", flags=flags)