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 "
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 $@
}
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
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}
}
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=$@ "
}
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=$@ "
}
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
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}"
}
}
}
}
tmr aws aws sso login
FTW 🤟
Top comments (1)
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 :)