Giter Club home page Giter Club logo

tfvar's Introduction

tfvar

GitHub release (latest by date) Coverage Status Go Report Card Package Documentation GitHub license

Banner of the project

tfvar is a Terraform's variable definitions template generator. It scans your Terraform configurations or modules and extracts the variables into formats of your choice for editing, e.g., tfvar, environment variables, etc.

For Terraform configuration that has input variables declared, e.g.,

variable "image_id" {
  type = string
}

variable "availability_zone_names" {
  type    = list(string)
  default = ["us-west-1a"]
}

variable "docker_ports" {
  type = list(object({
    internal = number
    external = number
    protocol = string
  }))
  default = [
    {
      internal = 8300
      external = 8300
      protocol = "tcp"
    }
  ]
}
  • tfvar will search for all input variables and generate template that helps user populates those variables easily:

    $ tfvar .
    availability_zone_names = ["us-west-1a"]
    docker_ports            = [{ external = 8300, internal = 8300, protocol = "tcp" }]
    image_id                = null
    
  • Note that default values are assigned to the definitions by default as shown above. Use the --ignore-default options to ignore the default values.

    $ tfvar . --ignore-default
    availability_zone_names = null
    docker_ports            = null
    image_id                = null
    
  • tfvar also provides other output formats:

    • In environment variable formats with -e flag:

      $ tfvar . -e
      export TF_VAR_availability_zone_names='["us-west-1a"]'
      export TF_VAR_docker_ports='[{ external = 8300, internal = 8300, protocol = "tcp" }]'
      export TF_VAR_image_id=''
      
    • The -r, --resource flag outputs all variables as tfe_variable resource of Terraform Enterprise (tfe) provider.

    • The -w, --workspace flag outputs all variables in the payload format for the Workspace Variables API https://www.terraform.io/docs/cloud/api/workspace-variables.html#sample-payload which can used together with jq to filter variables by key name.

      $ tfvar -w . | jq '. | select(.data.attributes.key == "region")'
      {
        "data": {
          "type": "vars",
          "attributes": {
            "key": "region",
            "value": "",
            "description": "",
            "category": "terraform",
            "hcl": false,
            "sensitive": false
          }
        }
      }
      
  • There is also --auto-assign option for those who wants the values from terraform.tfvars[.json], *.auto.tfvars[.json], and environment variables (TF_VAR_ followed by the name of a declared variable) to be assigned to the generated definitions automatically.

    $ export TF_VAR_availability_zone_names='["custom_zone"]'
    $ tfvar . --auto-assign
    availability_zone_names = ["custom_zone"]
    docker_ports            = [{ external = 8300, internal = 8300, protocol = "tcp" }]
    image_id                = null
    
  • Like the terraform (plan|apply) CLI tool, individual vairables can also be specified via --var option.

    $ tfvar . --var=availability_zone_names='["custom_zone"]' --var=image_id=abc123
    availability_zone_names = ["custom_zone"]
    docker_ports            = [{ external = 8300, internal = 8300, protocol = "tcp" }]
    image_id                = "abc123"
    
  • Variables in file can also be specified via --var-file option.

    $ cat my.tfvars
    image_id = "xyz"
    $ tfvar . --var-file my.tfvars
    availability_zone_names = ["us-west-1a"]
    docker_ports            = [{ external = 8300, internal = 8300, protocol = "tcp" }]
    image_id                = "xyz"
    
  • Multiple files can be specified via providing more --var-file options, variables overrides as for terraform command.

    $ cat my.tfvars
    image_id = "xyz"
    
    $ cat other.tfvars
    image_id = "abc"
    
    $ tfvar . --var-file my.tfvars --var-file other.tfvars
    image_id = "abc"
    

For more info, checkout the --help page:

$ tfvar --help
Generate variable definitions template for Terraform module as
one would write it in variable definitions files (.tfvars).

Usage:
  tfvar [DIR] [flags]

Flags:
  -a, --auto-assign            Use values from environment variables TF_VAR_* and
                               variable definitions files e.g. terraform.tfvars[.json] *.auto.tfvars[.json]
  -d, --debug                  Print debug log on stderr
  -e, --env-var                Print output in export TF_VAR_image_id=ami-abc123 format
  -h, --help                   help for tfvar
      --ignore-default         Do not use defined default values
  -r, --resource               Print output in Terraform Enterprise (tfe) provider's tfe_variable resource format
      --var stringArray        Set a variable in the generated definitions.
                               This flag can be set multiple times.
      --var-file stringArray   Set variables from a file.
                               This flag can be set multiple times.
  -v, --version                version for tfvar
  -w, --workspace              Print output variables as payloads for Workspace Variables API

Installation

brew install shihanng/tfvar/tfvar
sudo port install tfvar

Debian, Ubuntu

curl -sLO https://github.com/shihanng/tfvar/releases/latest/download/tfvar_linux_amd64.deb
dpkg -i tfvar_linux_amd64.deb

RedHat, CentOS

rpm -ivh https://github.com/shihanng/tfvar/releases/latest/download/tfvar_linux_amd64.rpm

Binaries

The release page contains binaries built for various platforms. Download the version matches your environment (e.g. linux_amd64) and place the binary in the executable $PATH e.g. /usr/local/bin:

curl -sL https://github.com/shihanng/tfvar/releases/latest/download/tfvar_linux_amd64.tar.gz | \
    tar xz -C /usr/local/bin/ tfvar

For Gophers

With Go already installed in your system, use go get

go get github.com/shihanng/tfvar

or clone this repo and make install

git clone https://github.com/shihanng/tfvar.git
cd tfvar
make install

Contributing

Want to add missing feature? Found bug ๐Ÿ›? Pull requests and issues are welcome. For major changes, please open an issue first to discuss what you would like to change โค๏ธ.

make lint
make test

should help with the idiomatic Go styles and unit-tests.

License

MIT

tfvar's People

Contributors

abuxton avatar breml avatar disaac avatar herbygillot avatar msurovcak avatar rs-steve-stevens avatar shihanng avatar steved avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

tfvar's Issues

Update tfvar for terraform 0.13

With terraform 0.13 the usage of count in modules has become possible. With the current version of tfvar, this fails with the following error messge:

Error: tfvar: loading config: main.tf:13,3-8: Reserved argument name in module block; The name "count" is reserved for use in a future version of Terraform., and 3 other diagnostic(s)

In order to fix this issue, the dependencies, especially for github.com/hashicorp/terraform need to be updated.

Support for `optional` type constrains is not implemented

Support for optional on the type constrains of variables which was introduced by hashicorp/terraform/#v1.3.0.

How to reproduce

create a simple file with the following content

variable "test_tfvar" {
  type = object({
    name    = optional(string)
  })
}

try to invoque tfvar and you'll get:

tfvar -a .
Error: tfvar: loading config: test.tf:3,12-28: Invalid type specification; Keyword "optional" is not a valid type constructor.

expectation

tfvar file is created with the values found on the environment and if an optional is not detected generation should ignore that field.

doesnt seem to work at all

I was really hopeful about this tool, but it doesn't work at all on any of the terraform I've tried it with.
it doesn't seem to recurse directories, and it only looks for specific filenames, so if I'm looking at an unfamiliar project that's not using the convention expected here I've got to go and manually parse the project anyway.

I tried it against this repo https://github.com/kbst/terraform-kubestack
and even if I specifically specify a file known to contain variables, it throws an error.
eg:

 tfvar . -d --var-file .terraform/modules/aks_zero/google/_modules/gke/variables.tf
2021-10-09T15:06:36.020+1030    DEBUG   cmd/cmd.go:89   Logger initialized
Error: tfvar: failed to get attributes: .terraform/modules/aks_zero/google/_modules/gke/variables.tf:1,1-9: Unexpected "variable" block; Blocks are not allowed here.

ideally I would type tfvars . and I'd get output of all the sources linked from the current project - worst case all the files in all the subdirectories!

Using `--var` in combination with `--var-file ` results in `--var` being ignored.

Using --var in combination with --var-file results in --var being ignored.

$cat my.tfvars
image_id = "xyz"

$tfvar . --var-file my.tfvars
image_id = "xyz"

$tfvar . --var=image_id="abc"
image_id = "abc"

## Not expected image_id should be "abc"
$tfvar . --var-file my.tfvars --var=image_id="abc"
image_id = "xyz"

##Ordering does not make a difference
$tfvar . --var=image_id="abc" --var-file my.tfvars
image_id = "xyz"

Does not yet support sensitive = true flag

Expected Behavior
Given a variables.tf file like

variable "password" {
  type        = string
  description = "the root password to use with the database"
  sensitive   = true
}

When I run the tfvar command
Then password variable is printed to stdout

Actual Behavior

An error is printed and processing of the variables file stops:

Error: tfvar: loading config: variables.tf:4,3-12: Unsupported argument; An argument named "sensitive" is not expected here.

Moved block being added to tfvars

@shihanng from terraform version 1.1 hashicorp introduced the moved block in order to rename resources (see here) It seems that this being added to the tfvars;
Error: tfvar: loading config: main.tf:1,1-6: Unsupported block type; Blocks of type "moved" are not expected here.
P.S. When adding the moved block manually in main.tf after the image is built, the plan works as expected.

Support for Terraform v1.5.x `import` block type

Terraform v1.5.x introduced the import block type:

This can be demonstrated by making a 'fake' tf file (as below)

import {
  to = null_resource.demo
  id = ""
}

and running tfvar .

Error: tfvar: loading config: import.tf:1,1-7: Unsupported block type; Blocks of type "import" are not expected here.

Could this block be added to the expected list?

Goreleaser tap formula uses deprecated `:unneeded`

Issue

When brew installing the tap for tfvar the following error message is received

Warning: Calling bottle :unneeded is deprecated! There is no replacement.
Please report this issue to the shihanng/tfvar tap (not Homebrew/brew or Homebrew/core):
  /opt/homebrew/Library/Taps/shihanng/homebrew-tfvar/tfvar.rb:9

The latest goreleaser has removed the deprecated :uneeded PR#2591 from the tap formula it generates. Should update github action to @v2

goreleaser not building for arm arm64

Currently the goreleaser config is only building for amd64/386 for darwin/windows/linux os. In order to support modern macos arm64 hardware binaries should additionally be built for those as well.

As a side effect the produced brew formula tap generated by goreleaser results in an error if installed on an arm64 mac.

brew readall
Error: Invalid formula: /opt/homebrew/Library/Taps/shihanng/homebrew-tfvar/tfvar.rb
formulae require at least a URL

This is due to a URL missing for the arch in the formula.

 on_macos do
    if Hardware::CPU.intel?
      url "https://github.com/shihanng/tfvar/releases/download/v0.4.1/tfvar_darwin_amd64.tar.gz"
      sha256 "3aa5a68097fbf7a7bc3de2ff02554481ce60d8e9514a3ced5ef6c3f6fa193f34"

      def install
        bin.install Dir['tfvar']
      end
    end
  end

Creating vars.tf entries automatically

It would be great if this tool allowed to avoid the painful process (ok, I'm lazy) of adding variable block definitions each time a new variable is referenced in a config.

e.g. if we have a file main.tf in the config like:

resource aws_instance example {
ami = var.ami
...
}

Would check to see if a variable definition exists already for ami and if not add this to a tfvar_vars.tf file.

Options:

  • append to existing vars.tf (specify file on command-line)
  • recurse into sub-directories aka modules
  • generate current outputs such as env vars, cli flags, terraform.tfvars

adding Comments to tfvars

can you add option to add comments written in variables.tf file to be printed for tfvars

eg:

# say hi
variable "hi" {
type = string
default = "hello"
}

output:

# say hi
hi = "hello"

add flag to output variables as tfe_variable resource, or tfe_variable api payload

I would like to add two flags;

-r --resource, which outputs variables as https://registry.terraform.io/providers/hashicorp/tfe/latest/docs/resources/variable and can be piped to a .tf file for usage

-w --workspace, which outputs https://www.terraform.io/docs/cloud/api/workspace-variables.html#sample-payload format of each var, and can be piped to an individual file per var so to be able to upload as payload from curl request.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.