DEV Community

Cover image for Terramate ❤️ Zsh
Roman Geraskin
Roman Geraskin

Posted on • Updated on • Originally published at rgeraskin.hashnode.dev

Terramate ❤️ Zsh

Terramate is an amazing tool to enhance your Terraform experience. However, there is a way to make it even more handy for everyday use.

Solve annoying things

1. Too long to type

Obvious one: terraform and terramate commands are too long to type=)

Use aliases:



# ~/.zshrc
alias tf="terraform "
alias tm="terramate "
alias tmg="terramate generate "


Enter fullscreen mode Exit fullscreen mode

You still have to type terraform after tm run because tm knows nothing about your aliases. But it will be solved below too.

2. Command chaining

Often, to execute a Terraform command, you need to run a preceding command. For example, before tf init, you should run tm generate. Similarly, before plan, you might need to run init, and so on.

You could use Makefiles or the terramate script run feature that comes with Terramate to handle command chaining. However, this only addresses the issue of chaining commands. Plus, you'd have to add these configurations to every repository you work with.

And it's still too much typing. You'll likely resort to using aliases anyway. So, why not start with shell configuration right from the start?

Zsh functions can help:



# ~/.zshrc
function tmi () {
  terramate generate && \
  terramate run terraform init $@
}
function tmp () {
  tmi $1 && \
  terramate run terraform plan -out=tfplan $@
}


Enter fullscreen mode Exit fullscreen mode

3. Tags for stacks

Tags are a fantastic feature of Terramate, especially if you're managing many stacks. They allow all tm run commands to be executed in stack directories selected by tags. However, their usability could be better—you always need to type them somewhere in the middle of a tm command.

For example, if you want to check the plan for the dev environment and then for the stage environment:



terramate run --tags=mngt:dev terraform plan
terramate run --tags=mngt:stage terraform plan


Enter fullscreen mode Exit fullscreen mode

To create the last command, you can use a sequence of keys like this before typing stage: up, option+left, option+left, left, esc, backspace.

Make functions smarter:



# ~/.zshrc
function tmi () {
  terramate generate && \
  terramate run --tags=$1 terraform init ${@:2}
}
function tmp () {
  tmi $1 && \
  terramate run --tags=$1 terraform plan -out=tfplan ${@:2}
}


Enter fullscreen mode Exit fullscreen mode

Now, you have fewer steps before you start typing stage: up, esc, backspace.

Additionally, you can specify plan options as the second or later arguments thanks to ${@:2} in the function.

4. Not sure about what you've typed?

Print the command before executing it:



# ~/.zshrc
function tmr () {
  print -z "terramate run --tags=$@ "
}


Enter fullscreen mode Exit fullscreen mode

So tmr dev:asd ls + enter will lead to terramate run --tags=dev:asd ls in the command line.

Let's put it all together



# ~/.zshrc
alias tf="terraform "
alias tm="terramate "
alias tmg="terramate generate "
function tmi () {
  terramate generate && \
  terramate run --tags=$1 terraform init ${@:2}
}
function tmv () {
  tmi $1 && \
  terramate run --tags=$1 terraform validate ${@:2}
}
function tmp () {
  tmi $1 && \
  terramate run --tags=$1 terraform plan -out=tfplan ${@:2}
}
function tma () {
  print -z "terramate run --tags=$1 terraform apply tfplan ${@:2}"
}
function tmpl () {
  tmi $1 && \
  terramate run --tags=$1 terraform providers lock -platform=linux_amd64 -platform=darwin_amd64 -platform=darwin_arm64 ${@:2}
}
function tmc () {
  tmi $1 && \
  terramate run --tags=$1 terraform console ${@:2}
}
function tmr () {
  print -z "terramate run --tags=$@ "
}


Enter fullscreen mode Exit fullscreen mode

Usage

Examples



tmi admin        # will run `terramate run --tags=admin terraform init`
tmp dev:infra    # will run `terramate run --tags=dev:infra terraform plan -out=tfplan`
tmr admin        # will print `terramate run --tags=admin` in prompt so you can run any command in the admin stack dir
tmr admin ls -la # will print `terramate run --tags=admin ls -la` in prompt, press 'enter' to execute `ls -la` in the admin stack dir or append more args


Enter fullscreen mode Exit fullscreen mode

Shortcuts description

Command Action
tf terraform
tm terramate
tmg terramate generate
tmi <TAGS> [ARGS] tm generate => tf init [ARGS]
tmv <TAGS> [ARGS] tm generate => tf init => tf validate [ARGS]
tmp <TAGS> [ARGS] tm generate => tf init => tf plan -out=tfplan [ARGS]
tma <TAGS> [ARGS] tf apply tfplan [ARGS]
tmpl <TAGS> [ARGS] tm generate => tf init => tf providers lock -platform=linux_amd64 -platform=darwin_amd64 -platform=darwin_arm64 [ARGS]
tml <TAGS> [ARGS] tm generate => tf init => tf console [ARGS]
tmc <TAGS> [ARGS] aws sso login [ARGS]
tmr <TAGS> <CMD> [ARGS] terramate run --tags=<TAGS> <CMD> [ARGS]

Bonus

Use different environment variable values for different stacks.

For example, if stacks use different AWS accounts, place the account name in the stack's globals and add it to your repository's root tm-file.



# repo root terramate.tm
terramate {
  config {
    run {
      env {
        AWS_PROFILE = "${global.aws_profile}"
      }
    }
  }
}


Enter fullscreen mode Exit fullscreen mode

tmr aws aws sso login FTW 🤟

Top comments (1)

Collapse
 
pwd9000 profile image
Marcel.L

Thanks for sharing this!
It is a very interesting tool I was not aware of and will definitely be looking more into.
Aliasing can go either way however, as with PowerShell it is not actually recommended as some users or consumers of code may not always understand what an alias means. But on the flip side it is also nice to have much shorter code :)