pushd is like cd but fancier
TL;DR pushd is cool for complex path navigation. I think.
I finally bothered to learn about pushd. Or at least the bare minimum about it, so that I can decide whether I need that or cd at a given point.
Main differences about pushd:
- the command returns the requested path -> you need to
>/dev/nullif you don’t care about the output - whenever you
pushd, you add the requested directory to a stack of paths- and then you can just
popdto go back to the previous path in the stack. Much fancier than a good ol’cd <path>!
- and then you can just

You can also choose the index at which you want to pop, you’re not limited to the last path in memory.
In my case pushd and popd are mostly interesting in scripts with intensive directory navigation. But most of the time cd .. is enough. Which probably explains why I never bothered to learn about it until now.
Terraform’s moved block for resource migrations
TL;DR a moved block takes care of informing Terraform of renamed resources and removes the need for a destroy-then-recreate cycle.
When you rename resources in your Terraform code, it happens that a “migration” is needed to simply assign the new name to the resources. The state must be modified (so that Terraform knows that this these two resources are the same, and sometimes even a recreation of the resource is needed. Pretty cumbersome for a change of name.
A typical example for me is with logs. I’d create my resource, let’s say an S3 bucket. Good practice wants us to name resources with a generic keyword unless we have something more meaningful to use, which gives us this:
resource "aws_s3_bucket" "this" {
bucket_prefix = "blblbl"
}
And then I would run a SAST analysis and dear old checkov would yell in my face:

And since for some weird (IMO) reason, S3 access can’t be logged using a CloudWatch log group, we need a second S3 bucket to log access of the first into.*
So now I have two buckets, and my this name gets confusing, so I update accordingly:
resource "aws_s3_bucket" "app" {
bucket_prefix = "blblbl"
}
resource "aws_s3_bucket" "logs" {
bucket_prefix = "blblbl-access-logs"
}
resource "aws_s3_bucket_logging" "app" {
bucket = aws_s3_bucket.app.id
target_bucket = aws_s3_bucket.logs.id
target_prefix = "access/"
}
And if I plan for these changes, Terraform shows me that my initial bucket will be destroyed:

And that’s because I renamed the bucket, but Terraform has no way to know that these buckets are supposed to be identical, even though they’d have identical configurations.
I’ve always worked around this behaviour (either by embracing the recreation when in the prototyping phase, or by describing the pitfall in the project docs), until stumbling upon our lord and saviour Anton Babenko’s example of a migrations.tf file. In there, he makes use of these moved blocks to avoid the issue. And it’s actually pretty cool.
By adding this simple block to the example above:
# Buckets declaration
moved {
from = aws_s3_bucket.this
to = aws_s3_bucket.app
}
Terraform then understands that the change is simply in the plan, and therefore does not register the operation as a destroy or a change, and it appears in the plan as follows:

And voilà! No need for a cumbersome recreation of resources.
I showed here a renaming example, but it works for many different situations, including the addition of a count condition of a module (which in itself means a renaming from module.this to module.this[0], but oh well…)
Anyways. This is cool and I’ll definitely use migration files in the future.
* The docs gracefully inform us that there’s no need to log the access of the logs bucket. Phew!
The lazy guy’s backend config
TL;DR: it’s possible to regroup the Terraform backend config and the project’s variables in a single file. It’s a bad idea. Don’t do that.
I was tired today, and when I’m tired I tend to get overwhelmed by the number of files I have to deal with. So I had the stupid idea to see whether I could combine my Terraform backend configuration with my variables in a single file. I usually split them in two files, backend.config and a tfvars one, but I was curious to see if the init command could read the backend config from the same file.
And oh wow, it does! Who could have seen this coming? Probably everybody else, since both files are written in HCL. Oh well.
The plot twist though, arrives upon the plan: Terraform does not know what to do with these weird variables. “Are you sure they’re needed? I don’t see them used anywhere!“

And I could very much see this become an issue because of how generic the backend config parameter names are. “What’s that bucket variable in your tfvars? Couldn’t you be a***d to choose more meaningful names?”
So yeah. Bad idea. Not worth the hassle.
git commit -m "That's all for today! Toodles"
Leave a comment