A 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.
- Parses and validates Terraform providers and resources.
- Dynamically generates
main.tf,variables.tf, andversions.tffiles. - Supports filtering Terraform provider schemas for required resources.
- Removes computed and invalid attributes from schemas.
- Ensures proper HCL formatting using
terraform fmt. - Logs detailed messages at various levels (info, debug, warn, error).
- Terraform binary installed (v1.3+)
- Go 1.23+
go.moddependencies (e.g.,terraform-json,terraform-exec,zclconf/go-cty).
# Add the plugin
asdf plugin add tmcg https://github.com/kbcz1989/asdf-tmcg.git
# Install a version
asdf install tmcg latest
# Set it globally
asdf global tmcg latest
# Verify installation
tmcg --versionARCH=$(uname -m | grep -q 'aarch64' && echo 'arm64' || echo 'amd64')
sudo wget "https://github.com/kbcz1989/tmcg/releases/latest/download/tmcg-linux-$ARCH" -O /usr/local/bin/tmcg
sudo chmod +x /usr/local/bin/tmcgARCH=$(uname -m | grep -q 'arm64' && echo 'arm64' || echo 'amd64')
curl -L "https://github.com/kbcz1989/tmcg/releases/latest/download/tmcg-darwin-$ARCH" -o /usr/local/bin/tmcg
chmod +x /usr/local/bin/tmcg$ARCH = if ($ENV:PROCESSOR_ARCHITECTURE -eq "ARM64") { "arm64" } else { "amd64" }
Invoke-WebRequest -Uri "https://github.com/kbcz1989/tmcg/releases/latest/download/tmcg-windows-$ARCH.exe" -OutFile "$Env:LOCALAPPDATA\tmcg.exe" -UseBasicParsingClone the repository:
git clone https://github.com/kbcz1989/tmcg.git
cd tmcg-generatorBuild the project:
go build -o tmcgRun the binary:
./tmcg --help| Flag | Description | Example |
|---|---|---|
--provider, -p |
Specify Terraform providers (e.g., 'hashicorp/aws:>=3.0'). |
-p 'hashicorp/aws:>=3.0' |
--resource, -r |
Specify resources (e.g., aws_instance:single, azurerm_resource_group:multiple). |
-r aws_instance:single |
--directory, -d |
The working directory for Terraform files. | -d ./output |
--binary, -b |
The path to the Terraform binary. | -b /usr/local/bin/terraform |
--log-level, -l |
Set the log level (e.g., debug, info, warn, error). |
-l debug |
--help, -h |
Show usage information. | |
--version, -v |
Show app version. | |
--desc-as-comment |
Include the description as a comment in multiple mode. | --desc-as-comment=true |
./tmcg -p hashicorp/aws:>=3.0 -r aws_instance:single -d ./output -l debugmain.tf: Contains resource definitions with dynamic blocks.variables.tf: Defines input variables for the resources.versions.tf: Specifies required providers and their versions.
Run all tests:
make test- Verifies resource and provider parsing.
- Ensures
main.tf,variables.tf, andversions.tfgeneration matches expectations. - Validates cleanup of HCL files and schema handling.
-
Parsing Provider and Resource Arguments
- The tool takes arguments for providers and resources passed via CLI flags.
- Providers can be specified with optional versions (e.g.,
hashicorp/aws:>=3.0). - Resources are parsed with an optional mode (
singleormultiple), defaulting tomultiple.
-
Building
versions.tf- The tool constructs a
versions.tffile based on the provided provider arguments. - The file specifies provider sources and version constraints.
- The tool constructs a
-
Running
terraform init- Once the
versions.tffile is created,tmcgrunsterraform initto download required providers. - This ensures that all dependencies are in place before schema processing.
- Once the
-
Fetching Terraform Provider Schema
- The tool fetches the full schema for the specified providers using
terraform providers schema. - This includes details of attributes, blocks, and their metadata (e.g., required, computed, optional).
- The tool fetches the full schema for the specified providers using
-
Filtering the Schema for Parsed Resources
- From the fetched schema, only the resources specified via CLI arguments are retained.
- This narrows down the schema to the required subset.
-
Removing Computed-Only Attributes
- The filtered schema is further refined by removing attributes that are only computed and cannot be configured by users.
-
Generating
main.tfandvariables.tf- Based on the filtered schema,
tmcggenerates:main.tf: A skeleton configuration for resources with all possible attributes.variables.tf: A file specifying the input variable types for Terraform.
- Based on the filtered schema,
-
Running
terraform validate- After generating the configuration files,
tmcgrunsterraform validateto check for errors or warnings. - This step helps identify any invalid or unsupported attributes.
- After generating the configuration files,
-
Removing Invalid Attributes
- If validation errors are detected,
tmcganalyzes the errors and removes invalid attributes from the filtered schema. - The process ensures the configuration adheres to the schema and Terraform constraints.
- If validation errors are detected,
-
Re-running Generation
- With the refined schema,
tmcgregeneratesmain.tfandvariables.tf. - This ensures the configurations are correct after invalid attributes are removed.
- With the refined schema,
-
Running
terraform fmt- The tool formats the generated Terraform configuration files for better readability and consistency.
-
Final Validation
- A final
terraform validateis executed to confirm the validity of the configurations.
- A final
Imagine 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:
- 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.
- Ensuring flexibility: To make a module reusable, you must expose configurable parameters for all relevant resource attributes.
- Keeping up with upstream changes: Terraform providers are frequently updated, and your module must remain compatible with the latest schema.
This is where tmcg can be helpful.
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:
- Comprehensive attribute support: All attributes supported by the upstream provider are included in the generated code, ensuring you don’t miss any critical options.
- Baseline for further customization: The generated module serves as a starting point, which you can refine and extend to meet specific requirements.
- Automated validation and cleanup: It automatically validates and filters out computed-only attributes that should not be user-configurable.
For 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:
- A
variables.tfwith all attributes defined and ready for customization. - A
main.tfimplementing these variables with proper references. - A
versions.tfthat enforces the required providers and Terraform version.
Use tmcg to specify resources and providers for your module. For instance:
tmcg --resource aws_instance:single --provider "hashicorp/aws:>=4.0" --directory my-moduleNavigate to the my-module directory, where you’ll find:
versions.tf: Ensures compatibility with the required Terraform version and provider version.variables.tf: Includes all possible attributes for theaws_instanceresource.main.tf: Implements the logic based on the variables.
From here, you can further tailor the module to fit your use case.
Run Terraform commands to validate and test the module:
terraform init
terraform validatetmcg ensures the code is clean and adheres to best practices, reducing manual effort and errors.
- Time-saving: Quickly generate a baseline for Terraform modules, avoiding repetitive tasks.
- Up-to-date: Leverage the latest upstream provider schemas to ensure compatibility with the newest features.
- Customization-friendly: The generated code is easy to expand and customize, making it suitable for real-world use.
A DevOps/TechOps engineer responsible for setting up cloud infrastructure can use tmcg to:
- Generate a module for managing EC2 instances.
- Quickly iterate over configurations for different environments (e.g., staging, production) by modifying the generated
variables.tf. - Stay compatible with the latest AWS provider by regenerating the module as provider schemas evolve.
By streamlining the module creation process, tmcg lets you focus on high-value tasks like optimizing resource configurations and scaling infrastructure.
Contributions are welcome! Feel free to fork the repository and submit pull requests.
Special thanks to:
- @benjy44 and @hampusrosvall for inspiring this project.
- Terraform for its amazing tooling and APIs.
- Go community for the fantastic libraries used in this project.
- ChatGPT for guiding and assisting in creating this tool and documentation.