Manage your infrastructure across multiple environments (development, staging, and production) and multiple layers (like multiple servers, networks, storage, databases) efficiently!
Avoid duplicating Terraform code (directory for each environment) by reusing it across multiple environments with dedicated JSON configuration files.
- Environment/layer configuration stored outside the Terrafom/OpenTofu code
- Terrafom/OpenTofu code, called tofi, should be generic enough to handle provided configuration to deploy same resources with different configurations
tfvars
andvariables
are automatically generated in the temporary folder with selected terraform code (tofi) = resulting in full set of the Terraform code and configuration variables- After temporary folder is ready it executes
terraform
ortofu
with specified parameters - Maintainins separate state files for each environment/layer = automaticaly/dynamic provides configuration for remote state managment (different path on the storage regarding configured layers/dimensions). So the deployed set (configuration+terraform) stored in different
tfstate
files in remote storage (S3, GCS)
Yes, you should check other Infrastructure as Code (IaC) orchestration tool for Terraform:
So why another tool?
- The more open source tools the better (for GitHub Copilot, not for Earth).
- The more choice, the better (there are countries where people have no choice).
- Imagine there is only AWS CloudFormation.
Organization with AWS resources and state stored in S3
./tofugu cook --config examples/.tofugu -o demo-org -d account:test-account -d datacenter:staging1 -t vpc -- init
./tofugu cook --config examples/.tofugu -o demo-org -d account:test-account -d datacenter:staging1 -t vpc -- plan
./tofugu cook --config examples/.tofugu -o demo-org -d account:test-account -d datacenter:staging1 -t vpc -- apply
Organization with Google Cloud resources and state stored in Google Cloud Storage
./tofugu cook --config examples/.tofugu -o gcp-org -d account:free-tier -t free_instance -- init
./tofugu cook --config examples/.tofugu -o gcp-org -d account:free-tier -t free_instance -- plan
./tofugu cook --config examples/.tofugu -o gcp-org -d account:free-tier -t free_instance -- apply
- Everything after
--
will be passed as parameters to thecmd_to_exec
-c
= to remove temp dir after anytofugu
execution (afterapply
ordestroy
and exitcode=0 temp dir removed automatically)-o
= name of theorganization
(subfolder in Inventory, tofies folders and in.tofugu
config section)-d
=dimension
to attach to tofu/terraform. You may specify as many-d
pairs as you need!-t
= name of thetofi
in thetofies
folder
Special json file with name tofi_manifest.json
in tofi
folder provides options for TofuGu.
Currently only dimensions
with list of the required/expecting dimensions (from Inventory Store)
You could set env variable toasterurl
to point to TofuGu-Toaster, like:
export toasterurl='https://accountid:accountpass@toaster.altuhov.su'
To generate your own credentials please go to https://toaster.altuhov.su/ , fill the form with Account Name, Email and press Create User
and you will receive generated credentials and ready-to-use export command like:
Please execute in shell to set toasterurl:
export toasterurl=https://6634b72292e9e996105de19e:generatedpassword@toaster.altuhov.su
With correct toasterurl
TofuGu will connect and receive all the required dimension data from the Toaster-ToasterDB.
Additional parameter could be passed to tofugu -w workspacename
. In general workspacename
is the branch name of the source repo where the dimension is stored. If TofuGu-Toaster will not find dimension with specified workspacename
it will try to return dimension from master
workspace/branch!
Toaster-ToasterDB Provides additional features for your CI and CD pipelines. For example, you need to receive a first-app.json in the CI pipeline, to check application configuration. Or you need a list of all the datacenters in datacenter dimension in Jenkins drop-down list to select to which datacenter to deploy application.
Swagger API docs (full API documentation and examples)
To upload/update dimensions in Toaster from your Inventory Files repo you could use inventory-to-toaster.sh script example and execute it like bash examples/inventory-to-toaster.sh examples/inventory/
Please join the Toaster-ToasterDB beta-testers!
If env variable toasterurl
is not set, TofuGu will use file-based configuration Storage (probably dedicated git repo), specified by the path configured in inventory_path
.
Examples:
When you set dimensions in the tofugu flags -d datacenter:staging1
, TofuGu will provide you inside tf-code next variables:
- var.tofugu_datacenter_name = will contain string
staging1
- var.tofugu_datacenter_data = will contain whole object from
staging1.json
- var.tofugu_datacenter_defaults = will contain whole object from
dim_defaults.json
IF filedim_defaults.json
exists!
Examples:
For example, you need to pass a variable (AWS region) from shell to the terraform code, simply set it and use!
Environment variable must start with tofugu_envvar_
prefix!
export tofugu_envvar_awsregion=us-east-1
In the TF code:
provider "aws" {
region = var.tofugu_envvar_awsregion
}
Env variables used in code example
Config file (in YAML format) path maybe provided by the --config
flag, for example: `
tofugu --config path_to_config/tofuguconfig cook -o demo-org -d account:test-account -d datacenter:staging1 -t vpc -- init
If --config
flag is not set, then it will try to load from default location $HOME/.tofugu
defaults:
tofies_path: examples/tofies
shared_modules_path: examples/tofies/shared-modules
inventory_path: examples/inventory
cmd_to_exec: tofu
backend:
bucket: default-tfstates
key: $tofugu_state_path
region: us-east-2
gcp-org:
backend:
bucket: gcp-tfstates
prefix: $tofugu_state_path
tofies_path
= relative path to the folder with terraform code (tofi
)shared_modules_path
= relative path to the folder with shared TF modules maybe used by anytofi
inventory_path
= relative path to the folder with jsonscmd_to_exec
= name of the binary to execute (tofu
orterraform
)backend
= Config values for backend provider. All the child key:values will be provided toinit
and$tofugu_state_path
will be replaced by generated path. For example, when you will executetofugu cook ...... -- init
, TofuGu actually will executeinit -backend-config=bucket=gcp-tfstates -backend-config=prefix=account_free-tier/free_instance.tfstate
At least
defaults:
backend:
bucket: default-tfstates
key: $tofugu_state_path
must be set in the config file! With key:values specific for the backend provider being used in org!
Other options contain hard-coded defaults:
defaults:
inventory_path: "examples/inventory"
shared_modules_path: ""
tofies_path: "examples/tofies"
cmd_to_exec: "tofu"
It is a good practice to move some generic terraform code to the modules
and reuse those modules in multiple terraform code (tofies)
Path to the folder with such private shared modules configured by shared_modules_path
parameter in .tofugu
configuration file.
This folder will be mounted/linked to the every temporary folder (set) so you could use any module by short path like
//use shared-module
module "vpc" {
source = "./shared-modules/create_vpc"
}
Examples:
AWS, Google Cloud and some other backends are supported! You could configure any backend provider in TofuGu Config file
For AWS S3 your terraform code (tofi
) should contains at least::
terraform {
backend "s3" {}
}
For Google Cloud Storage your terraform code (tofi
) should contains at least::
terraform {
backend "gcs" {}
}
If for the demo-org
config bucket
is set, then $tofugu_state_path
will be like: dimName1_dimValue1/dimNameN_dimValueN/tofiName.tfstate
If for the demo-org
config bucket
is NOT set, then $tofugu_state_path
will be like org_demo-org/dimName1_dimValue1/dimNameN_dimValueN/tofiName.tfstate
This could be useful, if you want to store by default tfstate for all the organisations in the same/default bucket default-tfstates
but for some specific organisation you need to store tfstates in dedicated bucket demo-org-tfstates
To simplify "Data Source Configuration" (data "terraform_remote_state" "tfstate" { }
) will be nice to have backend config values as tfvars.
var.tofugu_backend_config
will contain all the parameters from TofuGu config (backend Section)
data "terraform_remote_state" "network" {
backend = "s3"
config = {
bucket = var.tofugu_backend_config.bucket
key = "network/terraform.tfstate"
region = var.tofugu_backend_config.region
}
}
data "terraform_remote_state" "free_instance" {
backend = "gcs"
config = {
bucket = var.tofugu_backend_config.bucket
prefix = "account_free-tier/free_instance.tfstate"
}
}
You will set key/prefix
to another tofie's tfstate, which outputs you want to use.
Recommended to enable plugin_cache_dir to reuse providers.
plugin_cache_dir = "$HOME/.terraform.d/plugin-cache"
plugin_cache_may_break_dependency_lock_file = true
Do not forget to create plugin-cache dir: mkdir "$HOME/.terraform.d/plugin-cache"
tofugu
is OpenTofu/Terraform version agnostic!
Required external tools/binaries: rsync
, ln
tofugu
is licensed with Apache License Version 2.0.
Please read the LICENSE file for more details.