{"id":24112541,"url":"https://github.com/kbcz1989/tmcg","last_synced_at":"2025-02-28T07:58:52.234Z","repository":{"id":268632711,"uuid":"899094294","full_name":"kbcz1989/tmcg","owner":"kbcz1989","description":"Helper app for writing Terraform modules","archived":false,"fork":false,"pushed_at":"2025-01-31T16:04:20.000Z","size":50,"stargazers_count":8,"open_issues_count":1,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-31T16:41:53.874Z","etag":null,"topics":["automation","devops","go","infrastructure-as-code","techops","terraform","tooling"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kbcz1989.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-12-05T15:58:39.000Z","updated_at":"2025-01-31T15:59:54.000Z","dependencies_parsed_at":"2024-12-18T01:28:02.907Z","dependency_job_id":"0f08447f-05db-4288-bb0a-659ccc805136","html_url":"https://github.com/kbcz1989/tmcg","commit_stats":null,"previous_names":["kbcz1989/tmcg"],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kbcz1989%2Ftmcg","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kbcz1989%2Ftmcg/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kbcz1989%2Ftmcg/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kbcz1989%2Ftmcg/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kbcz1989","download_url":"https://codeload.github.com/kbcz1989/tmcg/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241120093,"owners_count":19912989,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["automation","devops","go","infrastructure-as-code","techops","terraform","tooling"],"created_at":"2025-01-11T03:45:27.102Z","updated_at":"2025-02-28T07:58:52.203Z","avatar_url":"https://github.com/kbcz1989.png","language":"Go","readme":"# Terraform Module Code Generator\n\n### Build and Test Status\n[![Build Status](https://github.com/kbcz1989/tmcg/actions/workflows/release.yml/badge.svg)](https://github.com/kbcz1989/tmcg/actions/workflows/release.yml)\n[![Tests](https://img.shields.io/github/actions/workflow/status/kbcz1989/tmcg/tests.yml?label=tests)](https://github.com/kbcz1989/tmcg/actions/workflows/tests.yml)\n\n\n### Versioning and Downloads\n![Go Version](https://img.shields.io/github/go-mod/go-version/kbcz1989/tmcg)\n![Latest Release](https://img.shields.io/github/v/release/kbcz1989/tmcg)\n![GitHub tag (latest SemVer)](https://img.shields.io/github/v/tag/kbcz1989/tmcg)\n![Downloads](https://img.shields.io/github/downloads/kbcz1989/tmcg/latest/total)\n\n### Code Quality and Metrics\n[![Go Report Card](https://goreportcard.com/badge/github.com/kbcz1989/tmcg)](https://goreportcard.com/report/github.com/kbcz1989/tmcg)\n[![Codecov](https://codecov.io/gh/kbcz1989/tmcg/branch/main/graph/badge.svg)](https://codecov.io/gh/kbcz1989/tmcg)\n\n![Build Size](https://img.shields.io/github/languages/code-size/kbcz1989/tmcg)\n![Languages](https://img.shields.io/github/languages/top/kbcz1989/tmcg)\n\n### Community and Contributions\n![Open Issues](https://img.shields.io/github/issues/kbcz1989/tmcg)\n![Contributors](https://img.shields.io/github/contributors/kbcz1989/tmcg)\n![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)\n\n### License and Miscellaneous\n![License](https://img.shields.io/github/license/kbcz1989/tmcg)\n![Markdown Style](https://img.shields.io/badge/markdown-friendly-yellow)\n![Powered by Go](https://img.shields.io/badge/powered%20by-Go-blue?logo=go)\n![Last Commit](https://img.shields.io/github/last-commit/kbcz1989/tmcg)\n\n\nA Go-based tool for dynamically generating Terraform modules, including `main.tf`, `variables.tf`, and `versions.tf`, by leveraging Terraform schemas and user-defined resource configurations.\n\n## Features\n\n- Parses and validates Terraform providers and resources.\n- Dynamically generates `main.tf`, `variables.tf`, and `versions.tf` files.\n- Supports filtering Terraform provider schemas for required resources.\n- Removes computed and invalid attributes from schemas.\n- Ensures proper HCL formatting using `terraform fmt`.\n- Logs detailed messages at various levels (info, debug, warn, error).\n\n## Requirements\n\n- Terraform binary installed (v1.3+)\n\n### For installation from source\n\n- Go 1.23+\n- `go.mod` dependencies (e.g., `terraform-json`, `terraform-exec`, `zclconf/go-cty`).\n\n## Installation\n\n### Installation with asdf version manager\n```shell\n# Add the plugin\nasdf plugin add tmcg https://github.com/kbcz1989/asdf-tmcg.git\n\n# Install a version\nasdf install tmcg latest\n\n# Set it globally\nasdf global tmcg latest\n\n# Verify installation\ntmcg --version\n```\n\n---\n\n### Manual installation\n\n### Linux:\n\n```shell\nARCH=$(uname -m | grep -q 'aarch64' \u0026\u0026 echo 'arm64' || echo 'amd64')\nsudo wget \"https://github.com/kbcz1989/tmcg/releases/latest/download/tmcg-linux-$ARCH\" -O /usr/local/bin/tmcg\nsudo chmod +x /usr/local/bin/tmcg\n```\n\n### macOS:\n\n```shell\nARCH=$(uname -m | grep -q 'arm64' \u0026\u0026 echo 'arm64' || echo 'amd64')\ncurl -L \"https://github.com/kbcz1989/tmcg/releases/latest/download/tmcg-darwin-$ARCH\" -o /usr/local/bin/tmcg\nchmod +x /usr/local/bin/tmcg\n```\n\n### Windows:\n\n```shell\n$ARCH = if ($ENV:PROCESSOR_ARCHITECTURE -eq \"ARM64\") { \"arm64\" } else { \"amd64\" }\nInvoke-WebRequest -Uri \"https://github.com/kbcz1989/tmcg/releases/latest/download/tmcg-windows-$ARCH.exe\" -OutFile \"$Env:LOCALAPPDATA\\tmcg.exe\" -UseBasicParsing\n```\n\n## Installation from Source\n\nClone the repository:\n\n```bash\ngit clone https://github.com/kbcz1989/tmcg.git\ncd tmcg-generator\n```\n\nBuild the project:\n\n```bash\ngo build -o tmcg\n```\n\nRun the binary:\n\n```bash\n./tmcg --help\n```\n\n## Usage\n\n### Command-Line Options\n\n| Flag                | Description                                                                         | Example                       |\n| ------------------- | ----------------------------------------------------------------------------------- | ----------------------------- |\n| `--provider, -p`    | Specify Terraform providers (e.g., `'hashicorp/aws:\u003e=3.0'`).                        | `-p 'hashicorp/aws:\u003e=3.0'`    |\n| `--resource, -r`    | Specify resources (e.g., `aws_instance:single`, `azurerm_resource_group:multiple`). | `-r aws_instance:single`      |\n| `--directory, -d`   | The working directory for Terraform files.                                          | `-d ./output`                 |\n| `--binary, -b`      | The path to the Terraform binary.                                                   | `-b /usr/local/bin/terraform` |\n| `--log-level, -l`   | Set the log level (e.g., `debug`, `info`, `warn`, `error`).                         | `-l debug`                    |\n| `--help, -h`        | Show usage information.                                                             |                               |\n| `--version, -v`     | Show app version.                                                                   |                               |\n| `--desc-as-comment` | Include the description as a comment in multiple mode.                              | `--desc-as-comment=true`      |\n\n### Example Command\n\n```bash\n./tmcg -p hashicorp/aws:\u003e=3.0 -r aws_instance:single -d ./output -l debug\n```\n\n### Output Files\n\n- **`main.tf`**: Contains resource definitions with dynamic blocks.\n- **`variables.tf`**: Defines input variables for the resources.\n- **`versions.tf`**: Specifies required providers and their versions.\n\n## Tests\n\nRun all tests:\n\n```bash\nmake test\n```\n\n### Key Test Features\n\n- Verifies resource and provider parsing.\n- Ensures `main.tf`, `variables.tf`, and `versions.tf` generation matches expectations.\n- Validates cleanup of HCL files and schema handling.\n\n## How `tmcg` Works\n\n1. **Parsing Provider and Resource Arguments**\n   - The tool takes arguments for providers and resources passed via CLI flags.\n   - Providers can be specified with optional versions (e.g., `hashicorp/aws:\u003e=3.0`).\n   - Resources are parsed with an optional mode (`single` or `multiple`), defaulting to `multiple`.\n\n2. **Building `versions.tf`**\n   - The tool constructs a `versions.tf` file based on the provided provider arguments.\n   - The file specifies provider sources and version constraints.\n\n3. **Running `terraform init`**\n   - Once the `versions.tf` file is created, `tmcg` runs `terraform init` to download required providers.\n   - This ensures that all dependencies are in place before schema processing.\n\n4. **Fetching Terraform Provider Schema**\n   - The tool fetches the full schema for the specified providers using `terraform providers schema`.\n   - This includes details of attributes, blocks, and their metadata (e.g., required, computed, optional).\n\n5. **Filtering the Schema for Parsed Resources**\n   - From the fetched schema, only the resources specified via CLI arguments are retained.\n   - This narrows down the schema to the required subset.\n\n6. **Removing Computed-Only Attributes**\n   - The filtered schema is further refined by removing attributes that are only computed and cannot be configured by users.\n\n7. **Generating `main.tf` and `variables.tf`**\n   - Based on the filtered schema, `tmcg` generates:\n     - **`main.tf`**: A skeleton configuration for resources with all possible attributes.\n     - **`variables.tf`**: A file specifying the input variable types for Terraform.\n\n8. **Running `terraform validate`**\n   - After generating the configuration files, `tmcg` runs `terraform validate` to check for errors or warnings.\n   - This step helps identify any invalid or unsupported attributes.\n\n9. **Removing Invalid Attributes**\n   - If validation errors are detected, `tmcg` analyzes the errors and removes invalid attributes from the filtered schema.\n   - The process ensures the configuration adheres to the schema and Terraform constraints.\n\n10. **Re-running Generation**\n    - With the refined schema, `tmcg` regenerates `main.tf` and `variables.tf`.\n    - This ensures the configurations are correct after invalid attributes are removed.\n\n11. **Running `terraform fmt`**\n    - The tool formats the generated Terraform configuration files for better readability and consistency.\n\n12. **Final Validation**\n    - A final `terraform validate` is executed to confirm the validity of the configurations.\n\n---\n\n## Real-World Scenario\n\nImagine you are tasked with writing a Terraform module for deploying resources, such as AWS instances or Azure resources. Crafting such modules can be a daunting task because:\n\n1. **You need to understand the resource schema in-depth or read docs line by line**: Terraform provider resources often support dozens of attributes, some required, others optional, and many computed.\n2. **Ensuring flexibility**: To make a module reusable, you must expose configurable parameters for all relevant resource attributes.\n3. **Keeping up with upstream changes**: Terraform providers are frequently updated, and your module must remain compatible with the latest schema.\n\nThis is where `tmcg` can be helpful.\n\n### How `tmcg` Solves This Problem\n\n`tmcg` generates Terraform module boilerplate code by leveraging Terraform provider schemas directly. Its approach is guided by the author's subjective best practices, emphasizing flexibility and extensibility:\n\n- **Comprehensive attribute support**: All attributes supported by the upstream provider are included in the generated code, ensuring you don’t miss any critical options.\n- **Baseline for further customization**: The generated module serves as a starting point, which you can refine and extend to meet specific requirements.\n- **Automated validation and cleanup**: It automatically validates and filters out computed-only attributes that should not be user-configurable.\n\nFor example, if you want to create a module for an AWS EC2 instance, instead of manually crafting the `variables.tf` and `main.tf`, you can run `tmcg` and instantly get:\n\n1. A `variables.tf` with all attributes defined and ready for customization.\n2. A `main.tf` implementing these variables with proper references.\n3. A `versions.tf` that enforces the required providers and Terraform version.\n\n### Example Workflow\n\n#### 1. Define Resources and Providers\n\nUse `tmcg` to specify resources and providers for your module. For instance:\n\n```bash\ntmcg --resource aws_instance:single --provider \"hashicorp/aws:\u003e=4.0\" --directory my-module\n```\n\n#### 2. Review and Expand\n\nNavigate to the `my-module` directory, where you’ll find:\n\n- `versions.tf`: Ensures compatibility with the required Terraform version and provider version.\n- `variables.tf`: Includes all possible attributes for the `aws_instance` resource.\n- `main.tf`: Implements the logic based on the variables.\n\nFrom here, you can further tailor the module to fit your use case.\n\n#### 3. Validate and Apply\n\nRun Terraform commands to validate and test the module:\n\n```bash\nterraform init\nterraform validate\n```\n\n`tmcg` ensures the code is clean and adheres to best practices, reducing manual effort and errors.\n\n### Benefits\n\n- **Time-saving**: Quickly generate a baseline for Terraform modules, avoiding repetitive tasks.\n- **Up-to-date**: Leverage the latest upstream provider schemas to ensure compatibility with the newest features.\n- **Customization-friendly**: The generated code is easy to expand and customize, making it suitable for real-world use.\n\n### Real-World Use Case\n\nA DevOps/TechOps engineer responsible for setting up cloud infrastructure can use `tmcg` to:\n\n1. Generate a module for managing EC2 instances.\n2. Quickly iterate over configurations for different environments (e.g., staging, production) by modifying the generated `variables.tf`.\n3. Stay compatible with the latest AWS provider by regenerating the module as provider schemas evolve.\n\nBy streamlining the module creation process, `tmcg` lets you focus on high-value tasks like optimizing resource configurations and scaling infrastructure.\n\n---\n\n## Contributing\n\nContributions are welcome! Feel free to fork the repository and submit pull requests.\n\n## Acknowledgments\n\nSpecial thanks to:\n\n- [@benjy44](https://github.com/benjy44) and [@hampusrosvall](https://github.com/hampusrosvall) for inspiring this project.\n- [Terraform](https://www.terraform.io) for its amazing tooling and APIs.\n- [Go](https://golang.org) community for the fantastic libraries used in this project.\n- **ChatGPT** for guiding and assisting in creating this tool and documentation.\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkbcz1989%2Ftmcg","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkbcz1989%2Ftmcg","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkbcz1989%2Ftmcg/lists"}