An open API service indexing awesome lists of open source software.

https://github.com/wayfair-incubator/pyterraformer


https://github.com/wayfair-incubator/pyterraformer

hacktoberfest

Last synced: 6 months ago
JSON representation

Awesome Lists containing this project

README

          

[![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/wayfair-incubator/pyterraformer/LICENSE)
[![PyPI](https://img.shields.io/pypi/v/pyterraformer.svg)](https://pypi.org/project/pyterraformer/)
[![Python Versions](https://img.shields.io/pypi/pyversions/pyterraformer.svg)](https://pypi.python.org/pypi/pyterraformer)
[![Downloads](https://img.shields.io/badge/dynamic/json.svg?label=downloads&url=https%3A%2F%2Fpypistats.org%2Fapi%2Fpackages%2Fpyterraformer%2Frecent&query=data.last_month&colorB=brightgreen&suffix=%2FMonth)](https://pypistats.org/packages/pyterraformer)

# Pyterraformer

[![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-2.0-4baaaa.svg)](CODE_OF_CONDUCT.md)

## About The Project

Pyterraformer is a library for reading, modifying, and writing *human readable terraform code*. This is in contrast to
libraries such as the excellent [pyhcl2](https://github.com/amplify-education/python-hcl2), which don't support writing
back in the human format. It is similar to [terraform-cdk](https://www.terraform.io/cdktf) in that it also enables
directly executing terraform from python as well, but is different in that it can produce human readable code to check
in. This opens up a range of options for creative developers.

Pyterraformer can be used for any of the following:

- bulk generation of human readable terraform code
- large scale refactoring
- process automation, since as CI
- accessing the power of Terraform directly from python
- introspecting a terraform repo to collect information
- and more!

## Parsing and Modifying

Specifically, this library would enable reading this string

```terraform
resource "aws_s3_bucket" "b" {
bucket = "my-tf-test-bucket"

tags = {
Name = "My bucket"
Environment = "Dev"
}
}
```

into python, directly modifying the tags, and writing it back.

Let's take a look.

```python
from pyterraformer import HumanSerializer

hs = HumanSerializer(terraform='/path/to/my/terraform/binary')

example_string:str = '''resource "aws_s3_bucket" "b" {
bucket = "my-tf-test-bucket"

tags = {
Name = "My bucket"
Environment = "Dev"
}
}'''

# parse a string into a list of terraform objects
namespace = hs.parse_string(example_string)

# get the bucket from that list
bucket = namespace[0]

# modify the bucket
bucket.tags["Environment"] = "Prod"
bucket.bucket = 'my-updated-bucket'

# and write the modified namespace back
# formatting requires a valid terraform binary to be provided
updated = hs.render_object(bucket, format=True)

assert updated == '''resource "aws_s3_bucket" "b" {
bucket = "my-updated-bucket"
tags = {
Name = "My bucket"
Environment = "Prod"
}
}'''

```

## Applying

If you just want to directly create/modify resources from python, you can do that too.

For example, creating or modifying GCS bucket with a local state store is as simple as the below.

```python
import os

from pyterraformer import Terraform, TerraformWorkspace, HumanSerializer, LocalBackend
from pyterraformer.core.generics import BlockList
from pyterraformer.core.resources import ResourceObject

class GoogleStorageBucket(ResourceObject):
"""Let's define a google storge bucket resource.
To get provider resources defined for you, check out the provider packages."""
_type = 'google_storage_bucket'

if __name__ == "__main__":
tf = Terraform(terraform_exec_path=r'/path/to/my/terraform/binary',
backend=LocalBackend(path=os.getcwd()))
workspace = TerraformWorkspace(terraform=tf, path=os.getcwd(), serializer=HumanSerializer(terraform=tf))

namespace = workspace.get_file_safe('resource.tf')

namespace.add_object(GoogleStorageBucket(
id='my-new-bucket',
name="my-new-bucket",
location="US-EAST1",
project="my-project",
force_destroy=True,
uniform_bucket_level_access=True,
website=BlockList([{
'not_found_page': "404.html"
}]),
cors=BlockList([{
'origin': [
"https://readthedocs.org"],
'method': [
"GET",
"HEAD",
"PUT",
"POST",
"DELETE"],
'response_header': [
"*"],
'max_age_seconds': 3601
}])
))

workspace.save()

application_output = workspace.apply()
```

## Next Steps

Read the [documentation](https://pyterraformer.readthedocs.io/en/latest/) to discover more, including how to work with
directories, files, apply terraform directly, and get IDE auto-completion for your favorite providers.

## Project Maturity
`pyterraformer` is under active development; we’re still working out key workflows and best practices. While it has
been used extensively in internal projects, the open-source version contains significant rewrites for improved flexibility.
We’re iterating fast and are likely to introduce breaking changes to existing APIs to improve the developer experience.
Feedback is appreciated.

### Installation

`pyterraformer` is [hosted on PyPI](https://pypi.org/project/pyterraformer/), and is installable
with [pip](https://pip.pypa.io/en/stable/):

```sh
pip install pyterraformer
```

Typed classes for IDE autocomplete and validation [if available] can be installed under the package name
pytf-[provider-owner]-[provider-name]

```sh
pip install pytf-hashicorp-aws

```

And then imported in the following way

```python
from pyterraformer.providers.hashicorp.aws import aws_s3_bucket

```

## Documentation

Primary documentation is on [Read the Docs](https://pyterraformer.readthedocs.io/en/latest/)

## Roadmap

See the [open issues](https://github.com/org_name/repo_name/issues) for a list of proposed features (and known issues).

## Contributing

Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any
contributions you make are **greatly appreciated**. For detailed contributing guidelines, please
see [CONTRIBUTING.md](CONTRIBUTING.md)

## License

Distributed under the `MIT License` License. See `LICENSE` for more information.

## Contact

Project Link: [https://github.com/org_name/repo_name](https://github.com/org_name/repo_name)

## Acknowledgements

This template adapted from
[https://github.com/othneildrew/Best-README-Template](https://github.com/othneildrew/Best-README-Template)