{"id":17053730,"url":"https://github.com/relrin/terraform-sage","last_synced_at":"2025-10-13T03:41:56.537Z","repository":{"id":57669530,"uuid":"202369714","full_name":"Relrin/terraform-sage","owner":"Relrin","description":"Cross-platform tool for easier Terraform deployments","archived":false,"fork":false,"pushed_at":"2021-05-07T10:16:05.000Z","size":53,"stargazers_count":10,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-09-24T00:51:38.387Z","etag":null,"topics":["cli","deployment","developer-tools","devops","rust","terraform"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Relrin.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}},"created_at":"2019-08-14T14:42:43.000Z","updated_at":"2022-06-30T14:15:36.000Z","dependencies_parsed_at":"2022-09-26T20:40:59.117Z","dependency_job_id":null,"html_url":"https://github.com/Relrin/terraform-sage","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/Relrin/terraform-sage","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Relrin%2Fterraform-sage","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Relrin%2Fterraform-sage/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Relrin%2Fterraform-sage/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Relrin%2Fterraform-sage/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Relrin","download_url":"https://codeload.github.com/Relrin/terraform-sage/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Relrin%2Fterraform-sage/sbom","scorecard":{"id":119666,"data":{"date":"2025-08-11","repo":{"name":"github.com/Relrin/terraform-sage","commit":"b703d38ba6ce13386d025d88d549cc9466f1c368"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":2.5,"checks":[{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Code-Review","score":0,"reason":"Found 0/17 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: BSD 3-Clause \"New\" or \"Revised\" License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: containerImage not pinned by hash: Dockerfile:1: pin your Docker image by updating rust:1.36-stretch to rust:1.36-stretch@sha256:67d871b18be731b54dfa8a01e72fae4cd188c8728dbda32fd8e7ebe10f372fa1","Warn: downloadThenRun not pinned by hash: ci/install.sh:19","Info:   0 out of   1 containerImage dependencies pinned","Info:   0 out of   1 downloadThenRun dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Signed-Releases","score":0,"reason":"Project has not signed or included provenance with any releases.","details":["Warn: release artifact v0.2.0 not signed: https://api.github.com/repos/Relrin/terraform-sage/releases/24280908","Warn: release artifact v0.1.0 not signed: https://api.github.com/repos/Relrin/terraform-sage/releases/19488281","Warn: release artifact v0.2.0 does not have provenance: https://api.github.com/repos/Relrin/terraform-sage/releases/24280908","Warn: release artifact v0.1.0 does not have provenance: https://api.github.com/repos/Relrin/terraform-sage/releases/19488281"],"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 19 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-16T02:12:51.526Z","repository_id":57669530,"created_at":"2025-08-16T02:12:51.527Z","updated_at":"2025-08-16T02:12:51.527Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279013518,"owners_count":26085368,"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","status":"online","status_checked_at":"2025-10-13T02:00:06.723Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["cli","deployment","developer-tools","devops","rust","terraform"],"created_at":"2024-10-14T10:13:04.558Z","updated_at":"2025-10-13T03:41:56.513Z","avatar_url":"https://github.com/Relrin.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# terraform-sage\n\nCross-platform tool for easier Terraform deployments\n\n - [Quick start](#quick-start)\n - [FAQ](#faq)\n - [Advanced usage](#advanced-usage)\n - [Project structure](#project-structure)\n - [Development](#development)\n - [License](#license)\n\n## Features\n\n- Template-based approach for work in multiple environments\n- Semi-automated deploys via command-line interface (as Terraform does)\n\n## Requirements\n\nTerraform \u003e= 0.11 (older not tested)\n\n## Quick start\n\n1. Install [Terraform](https://learn.hashicorp.com/terraform/getting-started/install.html).\n\n2. Download executable/binary file in according to the used operation system from the [releases page](https://github.com/Relrin/terraform-sage/releases).\n\n3. Link executable/binary file to operation system, so you could invoke `terraform-sage` everywhere:\n\n    - Linux / Mac OS\n  \n        Move the binary file to the `/usr/local/bin` directory and restart the terminal\n        ```\n        mv ~/Downloads/terraform-sage /usr/local/bin\n        ```\n    \n    - Windows\n    \n        1. Right click on the Windows Logo and select the `System` menu item.\n        2. Click on the `Advanced System Settings` button.\n        3. Click on the `Environment Variables` button.\n        4. Select your `PATH` variable and click in the `Edit` button.\n        5. Click on the `New` button.\n        6. Add the file path to the directory with the `terraform-sage` executable.\n        7. Click on the `OK` button a couple of times for applying changes.\n\n4. Go to your directory with code and create a directory for terraform files. For example, let's name it `terraform`.\n\n5. Inside of the `terraform` directory, create the `configs` directory. This directory will store all required Terraform modules related for each environment. So you will get something like this:\n    ```\n    \u003csources\u003e\n    ├ docker\n    ├ microservice\n    └ terraform\n      └ configs\n        ├ dev\n        │  ├ ... \n        │  └ variables.tf\n        ├ staging\n        │  ├ ...\n        │  └ variables.tf\n        └ production\n           ├ ...\n           └ variables.tf\n    ```\n    The `configs` directory is required and used for correct and smooth work of this wrapper. The `terraform-sage` will track environments defined in `configs` directory and will make an according action depends on the invoked Terraform command.\n    \n    P.S. Also see the [project structure](#project-structure) section for more information about recommended project structure.\n\n6. Create the base template (I recommend to name it as the `main.tpl`), that stores main definition of your resources and a backend storage for Terraform state. For making the writing base template easier, I recommend you to start with from `main.tf` module where you will describe everything what you need and then rename it to `main.tpl`. After when all resources / modules are described you will need to specify one of available [backend storages](https://www.terraform.io/docs/backends/types/index.html) for Terraform states, and then append `{{CONFIG_NAME}}` string to the key (which is basically is the file name for Terraform state), like this:\n    ```\n    terraform {\n      backend \"s3\" {\n        bucket = \"state-bucket\"\n        key    = \"terraform/state-{{CONFIG_NAME}}.tfstate\"\n        region = \"us-east-1\"\n      }\n    }\n    ```\n    The `{{CONFIG_NAME}}` string is using as the template parameter that will be replaced on the used environment name during the `terraform-sage` command call. This feature will help us in handling different environments without duplicating source code of the `main.tf` file. \n\n7. Then, instead of direct calls to Terraform CLI, you can use the following commands:\n    ```\n    terraform-sage init\n    terraform-sage plan\n    terraform-sage apply\n    terraform-sage destroy\n    terraform-sage output\n    ```\n    Also CLI provides two additional commands for generating Terraform's `main.tf` modules and retrieving the list of available environments.\n    ```\n    terraform-sage generate\n    terraform-sage list\n    ```\n    For more information about acceptable arguments and options for each command, call any desired command with the `--help` option.\n\n## F.A.Q.\n**Q**: Why this tool / wrapper was written?  \n**A**: Being a quite lazy developer, I tired of writing long Terraform command calls with specifying used `*.tf` / `*.tfvars` modules when you need to create or update something on any existing environment. The mess with modules increases when developers are using different operation systems and \"additional\" scripts for simplifying their Terraform workflows.\n\n**Q**: How can I pass extra arguments for Terraform command (e.g. `terraform-sage apply`)?  \n**A**: For this case you will need to append `.` in the end, and then specify a list of arguments as you were working with actual Terraform CLI, like this:\n```\nterraform apply dev --dir=examples/approach_two . -var-file=my-variables.tf\n```\n\n## Advanced usage\nTerraform-sage tool also provides a way to define additional context for each used environment. For this you will need to create a new file with the `context.toml` name in the root configs folder. As the result we will have the following project structure:\n```\nterraform\n├ configs\n│  ├ dev\n│  │  ├ secrets.tf\n│  │  └ variables.tf\n│  ├ staging\n│  │  ├ secrets.tf\n│  │  └ variables.tf\n│  └ production\n│  │  ├ secrets.tf\n│  │  └ variables.tf\n│  └  context.toml\n└ main.tpl\n```\n\nThe `context.toml` file contains placeholders for the template engine which is using during the generation of the `main.tf` file. Each section has the same name as the folder with variables for your environment. Under each section you need to specify key-pair values that supposed to be used in the appropriate context.\n\nAn example the definitions:\n```\n[dev]\nbucket_name = \"dev\"\nprofile = \"aws-dev-account\"\n\n[product]\nbucket_name = \"prod\"\nprofile = \"aws-prod-account\"\n```\nAfter it, you will need to declare placeholders in the appropriate places in the `main.tpl`, like this:\n```\nprovider \"aws\" {\n  profile = \"{{profile}}\"\n  region  = \"us-east-1\"\n}\n\n# ...\n\nresource \"aws_s3_bucket\" \"bucket\" {\n  bucket = \"terraform-sage-bucket\"\n  acl    = \"private\"\n\n  tags = {\n    \"Name\": \"{{bucket_name}}\"\n    \"EnvironmentType\" = \"${var.environment}\"\n  }\n}\n```\nAnd then you're ready to go! Just call the `terraform-sage apply dev` command (or any other suitable to you) without any further changes.\n\n## Project structure\n\nThe `terraform-sage` application relies on the certain project structure for a correct work. Therefore, I recommend to developers two ways of organizing their own projects:\n- Approach #1:\n\n  ```\n  terraform\n  ├ configs\n  │  ├ dev\n  │  │  ├ secrets.tf\n  │  │  └ variables.tf\n  │  ├ staging\n  │  │  ├ secrets.tf\n  │  │  └ variables.tf\n  │  └ production\n  │     ├ secrets.tf\n  │     └ variables.tf\n  ├ resources\n  │  ├ rds\n  │  │  ├ main.tf\n  │  │  ├ output.tf\n  │  │  └ variables.tf\n  │  └ sqs\n  │     ├ main.tf\n  │     ├ output.tf\n  │     └ variables.tf\n  └ main.tpl\n  ```\n\n  Pros:\n\n  - Dependant resources are splitted into [Terraform modules](https://www.terraform.io/docs/configuration/modules.html), therefore it is easier to re-use in other projects.\n  - Easier to manage projects which have a lot of dependencies.\n  - `main.tpl` file is relatively small and contains only a minimum amount of code\n\n  Cons:\n\n  - Requires more boilerplate code when providing extra arguments from the main executable Terraform configuration to dependant resources.\n\n- Approach #2:\n\n  ```\n  terraform\n  ├ configs\n  │  ├ dev\n  │  │  ├ secrets.tf\n  │  │  └ variables.tf\n  │  ├ staging\n  │  │  ├ secrets.tf\n  │  │  └ variables.tf\n  │  └ production\n  │     ├ secrets.tf\n  │     └ variables.tf\n  └ main.tpl\n  ```\n\n  Pros:\n\n  - A good choice for small projects with a couple of resources\n  - Easy to pass arguments to dependant resources\n\n  Cons:\n\n  - During the evolution of the project, `main.tpl` file can contain a lot of dependant resources\n\n## Development\n\nTo start developing you will need:\n\n- [Docker](https://docs.docker.com/install/)\n- [Docker-compose](https://docs.docker.com/compose/install/)\n\nBefore attaching to the node, you will need to build up the local dev image and start it in the detached mode. Run the following command from the project root folder:\n\n```\ndocker-compose -f docker-compose.dev.yml up -d\n```\n\nThen connect to the `app` node with bash via `exec` command:\n\n```\ndocker-compose -f docker-compose.dev.yml exec app bash\n```\n\nAnd now, you're ready to go! Use the `cargo` tool command inside of the container as you would like.\n\n## License\n\nThe terraform-sage project is published under BSD license. For more details read the [LICENSE](https://github.com/Relrin/terraform-sage/blob/master/LICENSE) file.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frelrin%2Fterraform-sage","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frelrin%2Fterraform-sage","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frelrin%2Fterraform-sage/lists"}