Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up

Terraform code generator for consistent codebase and DRY

License

NotificationsYou must be signed in to change notification settings

0xDones/tfgen

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

67 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

MaintenanceGitHub go.mod Go version of a Go moduleGitHub stars

Terragrunt alternative to keep your Terraform code consistent and DRY

Overview

What is tfgen

tfgen is useful for maintaining and scaling aTerraform Monorepo, in which you provision resources in a multi-environment/account setup. It is designed to create consistent Terraform definitions, like backend (with dynamic key), provider, and variables for each environment/account, as defined in a set of YAML configuration files.

Why tfgen

Terragrunt - a thin wrapper for Terraform that provides extra tools for working with multiple Terraform modules - is a great tool and inspired me a lot to createtfgen, but instead of being a wrapper for the Terraform binary,tfgen just creates Terraform files from templates and doesn't interact with Terraform at all. Terraform will be used independently on your local environment or in your CI system to deploy the resources.

  • This is not just a tool, it's a way of doing things
  • Keep your Terraform configuration consistent across the environments
  • Reduce the risk of making mistakes while copying+pasting your backend, provider, and other common Terraform definitions
  • Increase your productivity
  • Scale your mono repo following the same pattern across the modules

Features

  • Builtin functionality to provide the remote state key dynamically
  • YAML file configuration
  • Templates are parsed usingGo templates

Getting Started

Prereqs

  • Docker or Go

Installation

git clone --depth 1 git@github.com:0xDones/tfgen.gitcd tfgen# Using Dockerdocker run --rm -v$PWD:/src -w /src -e GOOS=darwin -e GOARCH=amd64 golang:alpine go build -o bin/tfgen# Using Gogo build -o bin/tfgenmv bin/tfgen /usr/local/bin

Note: when building using Docker, changeGOOS=darwin toGOOS=linux orGOOS=windows based on your system

Usage

Basic Usage

$ tfgenhelptfgen is a devtool to keep your Terraform code consistent and DRYUsage:  tfgen [command]Available Commands:  clean       clean templates from the target directory  completion  Generate the autocompletion scriptfor the specified shellexec        Execute the templatesin the given target directoryhelp        Help about anycommandFlags:  -h, --helphelpfor tfgen  -v, --verbose   verbose outputUse"tfgen [command] --help"for more information about a command.

Configuration files

The configuration files are written in YAML and have the following structure:

---root_file:boolvars:var1:value1var2:value2template_files:template1.tf:|    template contenttemplate2.tf:|    template content

How config files are parsed

tfgen will recursively look for all.tfgen.yaml files from the target directory up to the parent directories until it finds theroot config file, if it doesn't find the file it will exit with an error. All the other files found on the way up are merged into the root config file, and theinner config file has precedence over the outer.

We have two types of configuration files:

  1. Root config
  2. Environment specific config

Root config

In the root config file, you can set variables and templates that can be reused across all environments. You need at least 1 root config file.

# infra-live/.tfgen.yaml---root_file:truevars:company:acmetemplate_files:_backend.tf:|    terraform {      backend "s3" {        bucket         = "my-state-bucket"        dynamodb_table = "my-lock-table"        encrypt        =true        key            = "{{ .Vars.tfgen_state_key }}/terraform.tfstate"        region         = "{{ .Vars.aws_region }}"        role_arn       = "arn:aws:iam::{{ .Vars.aws_account_id }}:role/terraformRole"      }    }_provider.tf:|    provider "aws" {      region = "{{ .Vars.aws_region }}"      allowed_account_ids = [        "{{ .Vars.aws_account_id }}"      ]    }_vars.tf:|    variable "env" {      type    = string      default = "{{ .Vars.env }}"    }

Note thataws_region,aws_account, andenv are variables that you need to provide in the environment-specific config.tfgen_state_key is provided by thetfgen, it will be explained below.

Environment specific config

In the environment-specific config file (non-root), you can pass additional configuration, or override configuration from the root config file. You can have multiple specific config files, all of them will be merged into the root one.

# infra-live/dev/.tfgen.yaml---root_file:falsevars:aws_account_id:111111111111aws_region:us-east-1env:dev# infra-live/prod/.tfgen.yaml---root_file:falsevars:aws_account_id:222222222222aws_region:us-east-2env:prodtemplate_files:additional.tf:|    # I'll just be created on modules inside the prod folder

Provided Variables

These variables are automatically injected into the templates:

  • tfgen_state_key: The path from the root config file to the target directory

Practical Example

Repository Structure

Theterraform-monorepo-example repository can be used as an example of how to structure your repository to leveragetfgen and also follow Terraform best practices.

.├── infra-live│   ├── dev│   │   ├── networking│   │   ├── s3│   │   ├── security│   │   ├── stacks│   │   └── .tfgen.yaml     # Environment specific config│   ├── prod│   │   ├── networking│   │   ├── s3│   │   ├── security│   │   ├── stacks│   │   └── .tfgen.yaml     # Environment specific config│   └── .tfgen.yaml         # Root config file└── modules    └── my-custom-module

Inside ourinfra-live folder, we have two environments, dev and prod. They are deployed in different aws accounts, and each one has a different role that needs to be assumed in the provider configuration. Instead of copying the files back and forth every time we need to create a new module, we'll lettfgen create it for us based on our configuration defined on the.tfgen.yaml config files.

Running theexec command

Let's create the common files to start writing our Terraform module

# If you didn't clone the example repo yetgit clone git@github.com:0xDones/terraform-monorepo-example.gitcd terraform-monorepo-example# Create a folder for our new modulemkdir -p infra-live/dev/s3/dev-tfgen-bucketcd infra-live/dev/s3/dev-tfgen-bucket# Generate the filestfgenexec.# Checking the result (See Output section)cat _backend.tf _provider.tf _vars.tf

This execution will create all the files inside the working directory, executing the templates and passing in all the variables declared in the config files.

Output

This will be the content of the files created bytfgen:

_backend.tf

terraform {backend"s3" {bucket="my-state-bucket"dynamodb_table="my-lock-table"encrypt=truekey="dev/s3/dev-tfgen-bucket/terraform.tfstate"region="us-east-1"role_arn="arn:aws:iam::111111111111:role/terraformRole"  }}

_provider.tf

provider"aws" {region="us-east-1"allowed_account_ids=["111111111111"  ]}

_vars.tf

variable"env" {type=stringdefault="dev"}

Next steps

After creating the common Terraform files, you'll probably start writing yourmain.tf file. So at this point, you already know what to do.

terraform initterraform plan -out tf.outterraform apply tf.out

Related

Have fun!

About

Terraform code generator for consistent codebase and DRY

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

[8]ページ先頭

©2009-2025 Movatter.jp