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().

METHOD DESCRIPTION
model_dump

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

write

Write Terraform json configuration file

init

Runs terraform init

plan

Runs terraform plan

apply

Runs terraform apply

destroy

Runs terraform destroy

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
 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
123
def model_dump(self, *args, **kwargs) -> dict[str, Any]:
    """Serialize model to match the structure of a Terraform json file."""
    self._configure_serializer(singular=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"])
    self._configure_serializer(singular=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_into_dump(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
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
157
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
179
180
181
182
183
184
185
186
187
188
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
190
191
192
193
194
195
196
197
198
199
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
201
202
203
204
205
206
207
208
209
210
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
212
213
214
215
216
217
218
219
220
221
def destroy(self, flags: list[str] = None):
    """
    Runs `terraform destroy`

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